From 02dac280d0c74a0109e09b613b0a0714caebaf35 Mon Sep 17 00:00:00 2001 From: David Tchepak Date: Thu, 2 Feb 2012 23:06:47 +1100 Subject: [PATCH 01/39] Extract category_link filter from category_generator.rb plugin Allows category_link to be used as a filter to display a link to any category. --- plugins/category_generator.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/plugins/category_generator.rb b/plugins/category_generator.rb index bb5fd32..77e06af 100644 --- a/plugins/category_generator.rb +++ b/plugins/category_generator.rb @@ -141,10 +141,7 @@ module Jekyll # Returns string # def category_links(categories) - dir = @context.registers[:site].config['category_dir'] - categories = categories.sort!.map do |item| - "#{item}" - end + categories = categories.sort!.map { |c| category_link c } case categories.length when 0 @@ -156,6 +153,17 @@ module Jekyll end end + # Outputs a single category as an link. + # + # +category+ is a category string to format as an link + # + # Returns string + # + def category_link(category) + dir = @context.registers[:site].config['category_dir'] + "#{category}" + end + # Outputs the post.date as formatted html, with hooks for CSS styling. # # +date+ is the date object to format as HTML. From 79aa4eb4f76619f0e5eef9e799cbc7e5d38f4465 Mon Sep 17 00:00:00 2001 From: Josep del Rio Date: Thu, 19 Apr 2012 00:15:05 +0200 Subject: [PATCH 02/39] Added robots.txt, with sitemap link --- .themes/classic/source/robots.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .themes/classic/source/robots.txt diff --git a/.themes/classic/source/robots.txt b/.themes/classic/source/robots.txt new file mode 100644 index 0000000..b18d5dc --- /dev/null +++ b/.themes/classic/source/robots.txt @@ -0,0 +1,7 @@ +--- +layout: nil +--- +User-agent: * +Disallow: + +Sitemap: {{ site.url }}/sitemap.xml \ No newline at end of file From bcbc95b142b807175d0b18611eb0743564819a7d Mon Sep 17 00:00:00 2001 From: Nathan Long Date: Thu, 12 Jul 2012 05:39:30 -0400 Subject: [PATCH 03/39] Example repo URL - see Github issue 516 --- Rakefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index d4dcb54..1b5ece6 100644 --- a/Rakefile +++ b/Rakefile @@ -299,7 +299,9 @@ task :setup_github_pages, :repo do |t, args| if args.repo repo_url = args.repo else - repo_url = get_stdin("Enter the read/write url for your repository: ") + puts "Enter the read/write url for your repository" + puts "(For example, 'git@github.com:your_username/your_username.github.com)" + repo_url = get_stdin("Repository url: ") end user = repo_url.match(/:([^\/]+)/)[1] branch = (repo_url.match(/\/[\w-]+.github.com/).nil?) ? 'gh-pages' : 'master' From 0d14d9cd0692fe6cf65e27f49da0247f98a45cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zhao=20L=C3=BC?= Date: Thu, 19 Jul 2012 22:09:48 -0700 Subject: [PATCH 04/39] Updated Github API to V3. Github API V2 has been removed. The response data format also changed. --- .themes/classic/source/javascripts/github.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.themes/classic/source/javascripts/github.js b/.themes/classic/source/javascripts/github.js index 678775a..8b79dad 100644 --- a/.themes/classic/source/javascripts/github.js +++ b/.themes/classic/source/javascripts/github.js @@ -10,15 +10,15 @@ var github = (function(){ return { showRepos: function(options){ $.ajax({ - url: "http://github.com/api/v2/json/repos/show/"+options.user+"?callback=?" + url: "https://api.github.com/users/"+options.user+"/repos?callback=?" , type: 'jsonp' , error: function (err) { $(options.target + ' li.loading').addClass('error').text("Error loading feed"); } , success: function(data) { var repos = []; - if (!data || !data.repositories) { return; } - for (var i = 0; i < data.repositories.length; i++) { - if (options.skip_forks && data.repositories[i].fork) { continue; } - repos.push(data.repositories[i]); + if (!data || !data.data) { return; } + for (var i = 0; i < data.data.length; i++) { + if (options.skip_forks && data.data[i].fork) { continue; } + repos.push(data.data[i]); } repos.sort(function(a, b) { var aDate = new Date(a.pushed_at).valueOf(), From 9d7240e47f8edd732b5f7912d13b95266a3f4098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zhao=20L=C3=BC?= Date: Thu, 19 Jul 2012 22:09:48 -0700 Subject: [PATCH 05/39] Updated Github API to V3. Github API V2 has been removed. The response data format also changed. --- .themes/classic/source/javascripts/github.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.themes/classic/source/javascripts/github.js b/.themes/classic/source/javascripts/github.js index 8b79dad..9e98b8c 100644 --- a/.themes/classic/source/javascripts/github.js +++ b/.themes/classic/source/javascripts/github.js @@ -3,7 +3,7 @@ var github = (function(){ var i = 0, fragment = '', t = $(target)[0]; for(i = 0; i < repos.length; i++) { - fragment += '
  • '+repos[i].name+'

    '+repos[i].description+'

  • '; + fragment += '
  • '+repos[i].name+'

    '+(repos[i].description||'')+'

  • '; } t.innerHTML = fragment; } From 0d222ba6b29b5a1a0a061cd7d00f373e2c655995 Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Tue, 31 Jul 2012 14:55:23 -0500 Subject: [PATCH 06/39] Updated gems and rubies to 1.9.3 --- .rbenv-version | 2 +- .rvmrc | 2 +- Gemfile.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.rbenv-version b/.rbenv-version index 0a95b9f..9bbcf15 100644 --- a/.rbenv-version +++ b/.rbenv-version @@ -1 +1 @@ -1.9.2-p290 +1.9.3-p0 diff --git a/.rvmrc b/.rvmrc index 35845a2..08dd0a7 100644 --- a/.rvmrc +++ b/.rvmrc @@ -1 +1 @@ -rvm use 1.9.2 +rvm use 1.9.3 diff --git a/Gemfile.lock b/Gemfile.lock index 1c1bf8d..5060be1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ GEM chunky_png (1.2.5) classifier (1.3.3) fast-stemmer (>= 1.0.0) - compass (0.12.1) + compass (0.12.2) chunky_png (~> 1.2) fssm (>= 0.2.7) sass (~> 3.1) @@ -24,12 +24,12 @@ GEM kramdown (~> 0.13) liquid (~> 2.3) maruku (~> 0.5) - kramdown (0.13.6) + kramdown (0.13.7) liquid (2.3.0) maruku (0.6.0) syntax (>= 1.0.0) posix-spawn (0.3.6) - pygments.rb (0.2.12) + pygments.rb (0.2.13) rubypython (~> 0.5.3) rack (1.4.1) rack-protection (1.2.0) @@ -41,7 +41,7 @@ GEM rubypython (0.5.3) blankslate (>= 2.1.2.3) ffi (~> 1.0.7) - sass (3.1.18) + sass (3.1.20) sinatra (1.3.2) rack (~> 1.3, >= 1.3.6) rack-protection (~> 1.2) From 6029981e35eef840207bfcab423a8056e648ae3f Mon Sep 17 00:00:00 2001 From: Ivo Wever Date: Thu, 9 Aug 2012 23:34:41 +0300 Subject: [PATCH 07/39] Fix for issue #622 The filters bundled with Octopress are not applied to files ending in `.md`, because the match in octopress_filters.rb does not match `.md`. --- plugins/octopress_filters.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/octopress_filters.rb b/plugins/octopress_filters.rb index 2ba93e9..091f75a 100644 --- a/plugins/octopress_filters.rb +++ b/plugins/octopress_filters.rb @@ -24,12 +24,12 @@ module Jekyll class ContentFilters < PostFilter include OctopressFilters def pre_render(post) - if post.ext.match('html|textile|markdown|haml|slim|xml') + if post.ext.match('html|textile|markdown|md|haml|slim|xml') post.content = pre_filter(post.content) end end def post_render(post) - if post.ext.match('html|textile|markdown|haml|slim|xml') + if post.ext.match('html|textile|markdown|md|haml|slim|xml') post.content = post_filter(post.content) end end From ea88b0fc9893776d757602fae66c3593d5edafd8 Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Thu, 6 Sep 2012 11:36:16 -0500 Subject: [PATCH 08/39] bumped rbenv version fixing #743 --- .rbenv-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rbenv-version b/.rbenv-version index 9bbcf15..f3a9c9a 100644 --- a/.rbenv-version +++ b/.rbenv-version @@ -1 +1 @@ -1.9.3-p0 +1.9.3-p194 From 53ca59d6d0aa79b67ef89dbef16d2550df97e11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zhao=20L=C3=BC?= Date: Thu, 19 Jul 2012 22:09:48 -0700 Subject: [PATCH 09/39] Updated Github API to V3. Github API V2 has been removed. The response data format also changed. --- .themes/classic/source/javascripts/github.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.themes/classic/source/javascripts/github.js b/.themes/classic/source/javascripts/github.js index 678775a..8b79dad 100644 --- a/.themes/classic/source/javascripts/github.js +++ b/.themes/classic/source/javascripts/github.js @@ -10,15 +10,15 @@ var github = (function(){ return { showRepos: function(options){ $.ajax({ - url: "http://github.com/api/v2/json/repos/show/"+options.user+"?callback=?" + url: "https://api.github.com/users/"+options.user+"/repos?callback=?" , type: 'jsonp' , error: function (err) { $(options.target + ' li.loading').addClass('error').text("Error loading feed"); } , success: function(data) { var repos = []; - if (!data || !data.repositories) { return; } - for (var i = 0; i < data.repositories.length; i++) { - if (options.skip_forks && data.repositories[i].fork) { continue; } - repos.push(data.repositories[i]); + if (!data || !data.data) { return; } + for (var i = 0; i < data.data.length; i++) { + if (options.skip_forks && data.data[i].fork) { continue; } + repos.push(data.data[i]); } repos.sort(function(a, b) { var aDate = new Date(a.pushed_at).valueOf(), From 6c26f907cc0cf4704aaf5377738721177ec048f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zhao=20L=C3=BC?= Date: Thu, 19 Jul 2012 22:09:48 -0700 Subject: [PATCH 10/39] Updated Github API to V3. Github API V2 has been removed. The response data format also changed. --- .themes/classic/source/javascripts/github.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.themes/classic/source/javascripts/github.js b/.themes/classic/source/javascripts/github.js index 8b79dad..9e98b8c 100644 --- a/.themes/classic/source/javascripts/github.js +++ b/.themes/classic/source/javascripts/github.js @@ -3,7 +3,7 @@ var github = (function(){ var i = 0, fragment = '', t = $(target)[0]; for(i = 0; i < repos.length; i++) { - fragment += '
  • '+repos[i].name+'

    '+repos[i].description+'

  • '; + fragment += '
  • '+repos[i].name+'

    '+(repos[i].description||'')+'

  • '; } t.innerHTML = fragment; } From a010c99289a9dedd963fb2100d38fb80a80ae7ea Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Sat, 29 Sep 2012 22:42:47 -0500 Subject: [PATCH 11/39] Twitter API call and links are now protocol relative --- .themes/classic/source/javascripts/twitter.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.themes/classic/source/javascripts/twitter.js b/.themes/classic/source/javascripts/twitter.js index c9b7519..1a5c154 100644 --- a/.themes/classic/source/javascripts/twitter.js +++ b/.themes/classic/source/javascripts/twitter.js @@ -41,9 +41,9 @@ function prettyDate(time) { function linkifyTweet(text, url) { // Linkify urls, usernames, hashtags - text = text.replace(/(https?:\/\/)([\w\-:;?&=+.%#\/]+)/gi, '$2') - .replace(/(^|\W)@(\w+)/g, '$1@$2') - .replace(/(^|\W)#(\w+)/g, '$1#$2'); + text = text.replace(/(https?:)(\/\/)([\w\-:;?&=+.%#\/]+)/gi, '$3') + .replace(/(^|\W)@(\w+)/g, '$1@$2') + .replace(/(^|\W)#(\w+)/g, '$1#$2'); // Use twitter's api to replace t.co shortened urls with expanded ones. for (var u in url) { @@ -62,7 +62,7 @@ function showTwitterFeed(tweets, twitter_user) { content = ''; for (var t in tweets) { - content += '
  • '+'

    '+''+prettyDate(tweets[t].created_at)+''+linkifyTweet(tweets[t].text.replace(/\n/g, '
    '), tweets[t].entities.urls)+'

    '+'
  • '; + content += '
  • '+'

    '+''+prettyDate(tweets[t].created_at)+''+linkifyTweet(tweets[t].text.replace(/\n/g, '
    '), tweets[t].entities.urls)+'

    '+'
  • '; } timeline.innerHTML = content; } @@ -70,7 +70,7 @@ function showTwitterFeed(tweets, twitter_user) { function getTwitterFeed(user, count, replies) { count = parseInt(count, 10); $.ajax({ - url: "http://api.twitter.com/1/statuses/user_timeline/" + user + ".json?trim_user=true&count=" + (count + 20) + "&include_entities=1&exclude_replies=" + (replies ? "0" : "1") + "&callback=?" + url: "//api.twitter.com/1/statuses/user_timeline/" + user + ".json?trim_user=true&count=" + (count + 20) + "&include_entities=1&exclude_replies=" + (replies ? "0" : "1") + "&callback=?" , type: 'jsonp' , error: function (err) { $('#tweets li.loading').addClass('error').text("Twitter's busted"); } , success: function(data) { showTwitterFeed(data.slice(0, count), user); } From bfbb8f32fb073b5eec466fd15062dd506cf2b22d Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Mon, 1 Oct 2012 07:28:30 -0500 Subject: [PATCH 12/39] Using https instead of protocol relative urls, for Pinboard and Twitter feeds --- .themes/classic/source/javascripts/pinboard.js | 4 ++-- .themes/classic/source/javascripts/twitter.js | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.themes/classic/source/javascripts/pinboard.js b/.themes/classic/source/javascripts/pinboard.js index 52577e2..a97df03 100644 --- a/.themes/classic/source/javascripts/pinboard.js +++ b/.themes/classic/source/javascripts/pinboard.js @@ -44,7 +44,7 @@ function Pinboard_Linkroll() { if (it.t.length > 0) { for (var i = 0; i < it.t.length; i++) { var tag = it.t[i]; - str += " " + this.cook(tag).replace(/^\s+|\s+$/g, '') + " "; + str += " " + this.cook(tag).replace(/^\s+|\s+$/g, '') + " "; } } str += "

    \n"; @@ -52,5 +52,5 @@ function Pinboard_Linkroll() { } } Pinboard_Linkroll.prototype = new Pinboard_Linkroll(); -pinboardNS_fetch_script("http://feeds.pinboard.in/json/v1/u:"+pinboard_user+"/?cb=pinboardNS_show_bmarks\&count="+pinboard_count); +pinboardNS_fetch_script("https://feeds.pinboard.in/json/v1/u:"+pinboard_user+"/?cb=pinboardNS_show_bmarks\&count="+pinboard_count); diff --git a/.themes/classic/source/javascripts/twitter.js b/.themes/classic/source/javascripts/twitter.js index 1a5c154..3e2dd0d 100644 --- a/.themes/classic/source/javascripts/twitter.js +++ b/.themes/classic/source/javascripts/twitter.js @@ -41,9 +41,9 @@ function prettyDate(time) { function linkifyTweet(text, url) { // Linkify urls, usernames, hashtags - text = text.replace(/(https?:)(\/\/)([\w\-:;?&=+.%#\/]+)/gi, '$3') - .replace(/(^|\W)@(\w+)/g, '$1@$2') - .replace(/(^|\W)#(\w+)/g, '$1#$2'); + text = text.replace(/(https?:\/\/)([\w\-:;?&=+.%#\/]+)/gi, '$2') + .replace(/(^|\W)@(\w+)/g, '$1@$2') + .replace(/(^|\W)#(\w+)/g, '$1#$2'); // Use twitter's api to replace t.co shortened urls with expanded ones. for (var u in url) { @@ -62,7 +62,7 @@ function showTwitterFeed(tweets, twitter_user) { content = ''; for (var t in tweets) { - content += '
  • '+'

    '+''+prettyDate(tweets[t].created_at)+''+linkifyTweet(tweets[t].text.replace(/\n/g, '
    '), tweets[t].entities.urls)+'

    '+'
  • '; + content += '
  • '+'

    '+''+prettyDate(tweets[t].created_at)+''+linkifyTweet(tweets[t].text.replace(/\n/g, '
    '), tweets[t].entities.urls)+'

    '+'
  • '; } timeline.innerHTML = content; } @@ -70,7 +70,7 @@ function showTwitterFeed(tweets, twitter_user) { function getTwitterFeed(user, count, replies) { count = parseInt(count, 10); $.ajax({ - url: "//api.twitter.com/1/statuses/user_timeline/" + user + ".json?trim_user=true&count=" + (count + 20) + "&include_entities=1&exclude_replies=" + (replies ? "0" : "1") + "&callback=?" + url: "https://api.twitter.com/1/statuses/user_timeline/" + user + ".json?trim_user=true&count=" + (count + 20) + "&include_entities=1&exclude_replies=" + (replies ? "0" : "1") + "&callback=?" , type: 'jsonp' , error: function (err) { $('#tweets li.loading').addClass('error').text("Twitter's busted"); } , success: function(data) { showTwitterFeed(data.slice(0, count), user); } From 2b67270f960563c55dd6c66495517bccc4f7fb17 Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Sat, 13 Oct 2012 15:36:25 -0500 Subject: [PATCH 13/39] Disabled Rsync delete by default. Closes #787 --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 1b5ece6..3addaaf 100644 --- a/Rakefile +++ b/Rakefile @@ -7,7 +7,7 @@ require "stringex" ssh_user = "user@domain.com" ssh_port = "22" document_root = "~/website.com/" -rsync_delete = true +rsync_delete = false deploy_default = "rsync" # This will be configured for you when you run config_deploy From 0ccd0679fdfd13da34b0236361abbd149a42a777 Mon Sep 17 00:00:00 2001 From: Liang Sun Date: Tue, 27 Nov 2012 10:18:12 +0800 Subject: [PATCH 14/39] To support url without domain name like /path/file You need to know if you would like to support this, each word in the title can not start with "/". --- plugins/backtick_code_block.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/backtick_code_block.rb b/plugins/backtick_code_block.rb index 40e7900..0e7cee4 100644 --- a/plugins/backtick_code_block.rb +++ b/plugins/backtick_code_block.rb @@ -2,7 +2,7 @@ require './plugins/pygments_code' module BacktickCodeBlock include HighlightCode - AllOptions = /([^\s]+)\s+(.+?)(https?:\/\/\S+)\s*(.+)?/i + AllOptions = /([^\s]+)\s+(.+?)(https?:\/\/\S+|\/\S+)\s*(.+)?/i LangCaption = /([^\s]+)\s*(.+)?/i def render_code_block(input) @options = nil From 49e97e53f5e92cacb05f0dd33b656d4c813d07ce Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Fri, 30 Nov 2012 21:42:46 -0500 Subject: [PATCH 15/39] Fixing English error pet-peeve. --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 3addaaf..8f54ae1 100644 --- a/Rakefile +++ b/Rakefile @@ -151,7 +151,7 @@ task :new_page, :filename do |t, args| end # usage rake isolate[my-post] -desc "Move all other posts than the one currently being worked on to a temporary stash location (stash) so regenerating the site happens much quicker." +desc "Move all other posts than the one currently being worked on to a temporary stash location (stash) so regenerating the site happens much more quickly." task :isolate, :filename do |t, args| stash_dir = "#{source_dir}/#{stash_dir}" FileUtils.mkdir(stash_dir) unless File.exist?(stash_dir) From 916b87a5457e68514c95a1e5f8a0eff324bed9e8 Mon Sep 17 00:00:00 2001 From: Johan Svensson Date: Sun, 9 Dec 2012 19:04:41 +0100 Subject: [PATCH 16/39] Rakefile option for any additional rsync arguments Added variable `rsync_args` --- Rakefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 3addaaf..55bb57b 100644 --- a/Rakefile +++ b/Rakefile @@ -8,6 +8,7 @@ ssh_user = "user@domain.com" ssh_port = "22" document_root = "~/website.com/" rsync_delete = false +rsync_args = "" # Any extra arguments to pass to rsync deploy_default = "rsync" # This will be configured for you when you run config_deploy @@ -237,7 +238,7 @@ task :rsync do exclude = "--exclude-from '#{File.expand_path('./rsync-exclude')}'" end puts "## Deploying website via Rsync" - ok_failed system("rsync -avze 'ssh -p #{ssh_port}' #{exclude} #{"--delete" unless rsync_delete == false} #{public_dir}/ #{ssh_user}:#{document_root}") + ok_failed system("rsync -avze 'ssh -p #{ssh_port}' #{exclude} #{rsync_args} #{"--delete" unless rsync_delete == false} #{public_dir}/ #{ssh_user}:#{document_root}") end desc "deploy public directory to github pages" From 72b4e8d5621dbb3c110fe2c273bcc3ac408ffc32 Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Tue, 18 Dec 2012 11:38:37 -0600 Subject: [PATCH 17/39] gist tag plugin now works with the latest changes GitHub gists and does not fail if you do not specify a filename. --- .themes/classic/sass/partials/_syntax.scss | 64 ++++++++++++---------- plugins/gist_tag.rb | 4 +- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/.themes/classic/sass/partials/_syntax.scss b/.themes/classic/sass/partials/_syntax.scss index 77ac8d7..5465286 100644 --- a/.themes/classic/sass/partials/_syntax.scss +++ b/.themes/classic/sass/partials/_syntax.scss @@ -1,44 +1,52 @@ .highlight, html .gist .gist-file .gist-syntax .gist-highlight { table td.code { width: 100%; } - .line-numbers { - text-align: right; - font-size: 13px; - line-height: 1.45em; - @if $solarized == light { - background: lighten($base03, 1) $noise-bg !important; - border-right: 1px solid darken($base02, 2) !important; - @include box-shadow(lighten($base03, 2) -1px 0 inset); - text-shadow: lighten($base02, 2) 0 -1px; - } @else { - background: $base02 $noise-bg !important; - border-right: 1px solid darken($base03, 2) !important; - @include box-shadow(lighten($base02, 2) -1px 0 inset); - text-shadow: darken($base02, 10) 0 -1px; - } - span { color: $base01 !important; } - padding: .8em !important; - @include border-radius(0); - } border: 1px solid $pre-border !important; } +.highlight .line-numbers, html .gist .gist-file .gist-syntax .highlight .line_numbers { + text-align: right; + font-size: 13px; + line-height: 1.45em; + @if $solarized == light { + background: lighten($base03, 1) $noise-bg !important; + border-right: 1px solid darken($base02, 2) !important; + @include box-shadow(lighten($base03, 2) -1px 0 inset); + text-shadow: lighten($base02, 2) 0 -1px; + } @else { + background: $base02 $noise-bg !important; + border-right: 1px solid darken($base03, 2) !important; + @include box-shadow(lighten($base02, 2) -1px 0 inset); + text-shadow: darken($base02, 10) 0 -1px; + } + span { color: $base01 !important; } + padding: .8em !important; + @include border-radius(0); +} + figure.code, .gist-file, pre { @include box-shadow(rgba(#000, .06) 0 0 10px); .highlight pre { @include box-shadow(none); } } +.gist .highlight, figure.code .highlight { + @include selection(adjust-color($base03, $lightness: 23%, $saturation: -65%), $text-shadow: $base03 0 1px); +} html .gist .gist-file { margin-bottom: 1.8em; position: relative; border: none; padding-top: image-height("code_bg.png") !important; + .highlight { + margin-bottom: 0; + } .gist-syntax { border-bottom: 0 !important; background: none !important; - .gist-highlight{ + .gist-highlight { background: $base03 !important; - pre { - @extend .pre-code; - } + } + .highlight pre { + @extend .pre-code; + padding: 0; } } .gist-meta { @@ -107,12 +115,11 @@ p, li { } .pre-code { - @include selection(adjust-color($base03, $lightness: 23%, $saturation: -65%), $text-shadow: $base03 0 1px); font-family: $mono !important; overflow: scroll; overflow-y: hidden; display: block; - padding: .8em !important; + padding: .8em; overflow-x: auto; line-height: 1.45em; background: $base03 $noise-bg !important; @@ -187,7 +194,7 @@ p, li { } .highlight, .gist-highlight { - pre { background: none; @include border-radius(none); border: none; padding: 0; margin-bottom: 0; } + pre { background: none; @include border-radius(0px); border: none; padding: 0; margin-bottom: 0; } margin-bottom: 1.8em; background: $base03; overflow-y: hidden; @@ -206,7 +213,9 @@ pre, .highlight, .gist-highlight { &::-webkit-scrollbar-thumb:horizontal { background: $solar-scroll-thumb; -webkit-border-radius: 4px; border-radius: 4px } } -.highlight code { @extend .pre-code; background: #000;} +.highlight code { + @extend .pre-code; background: #000; +} figure.code { background: none; padding: 0; @@ -250,4 +259,3 @@ figure.code { text-shadow: #cbcccc 0 1px 0; padding-left: 3em; } - diff --git a/plugins/gist_tag.rb b/plugins/gist_tag.rb index 74dd3b3..5f590e9 100644 --- a/plugins/gist_tag.rb +++ b/plugins/gist_tag.rb @@ -40,7 +40,9 @@ module Jekyll end def script_url_for(gist_id, filename) - "https://gist.github.com/#{gist_id}.js?file=#{filename}" + url = "https://gist.github.com/#{gist_id}.js" + url = "#{url}?file=#{filename}" unless filename.nil? or filename.empty? + url end def get_gist_url_for(gist, file) From c18de558759dff2c77e6e0fc3ce2ad7a9f3fea99 Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Wed, 26 Dec 2012 17:18:29 -0600 Subject: [PATCH 18/39] Titles in code plugins can have slashes in them. Closes #892 --- plugins/backtick_code_block.rb | 2 +- plugins/code_block.rb | 8 ++++---- source/images/icon-sdc231d6676.png | Bin 0 -> 1513 bytes 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 source/images/icon-sdc231d6676.png diff --git a/plugins/backtick_code_block.rb b/plugins/backtick_code_block.rb index 0e7cee4..8e2c114 100644 --- a/plugins/backtick_code_block.rb +++ b/plugins/backtick_code_block.rb @@ -2,7 +2,7 @@ require './plugins/pygments_code' module BacktickCodeBlock include HighlightCode - AllOptions = /([^\s]+)\s+(.+?)(https?:\/\/\S+|\/\S+)\s*(.+)?/i + AllOptions = /([^\s]+)\s+(.+?)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/i LangCaption = /([^\s]+)\s*(.+)?/i def render_code_block(input) @options = nil diff --git a/plugins/code_block.rb b/plugins/code_block.rb index 44e3494..62c551a 100644 --- a/plugins/code_block.rb +++ b/plugins/code_block.rb @@ -49,8 +49,8 @@ module Jekyll class CodeBlock < Liquid::Block include HighlightCode include TemplateWrapper - CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)\s+(.+)/i - CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i + CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/i + CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/\S+|\/\S+)/i Caption = /(\S[\S\s]*)/ def initialize(tag_name, markup, tokens) @title = nil @@ -63,10 +63,10 @@ module Jekyll end if markup =~ CaptionUrlTitle @file = $1 - @caption = "
    #{$1}#{$4}
    " + @caption = "
    #{$1}#{$3}
    " elsif markup =~ CaptionUrl @file = $1 - @caption = "
    #{$1}link
    " + @caption = "
    #{$1}link
    " elsif markup =~ Caption @file = $1 @caption = "
    #{$1}
    \n" diff --git a/source/images/icon-sdc231d6676.png b/source/images/icon-sdc231d6676.png new file mode 100644 index 0000000000000000000000000000000000000000..38ef928f78e5684b25350ca827535045008ae8bc GIT binary patch literal 1513 zcmeAS@N?(olHy`uVBq!ia0vp^3P7B|!3-q5|1_*(U|?Jx;1l8sKxN$%wN(#wXC5}*@!D+9 zTk|#7t+zk5U2xQQ-{{G!rwD(YGW#+Ej&fl;vu$(cF%6^+y8FI};E-Ns#qkDWYo z{?hG-PdEaktaqH|f zdmrIInd9~E@9o|FTK?ab2nW_V9x^mv~(qjKcr)eRPsa~25j_%85TTK>JN{N7jj>)&h(E_k%>K3zS(=6Ch}_wT>&7JfKo z{*U+u#+eKev!*df7){GfaEK~-Z$D+OcF+>Xi3hyh9VfNL9+?nRBT&OI^WP3$4h7zH zVbueVg^W`|dK?cid$(?Ne8Oaq;^mn1e}k0%nw_FXoa_rKJtoNo&RSv9zxO@EuAm93 zEON6&9TrVse|aK2N{}UNQOZH5Gb*!O4+z}&ogl*4Taa@?v~g)-C+~$xk=;3mI;P*f z;xkjQtt`hpFe1I8m?uN0Q91me%Ddm$9JwcB15ek=1$9cS*Yeh5{A(BUFgeus+i9Uy zpLX)tY_L5fn#%Ahdwb-rpsCAZ%61+)yJM~XG*O>bN3(w&ihFtZM&CiBGZxDWh0@nl zu5NrWrMSP&@W@mRAHxR!^6)pmkIz4`XX~wFK?dek>wRs1#-y81x^Rlg$z^0|L! z3zs>S{GIEzhoSNH8!@p~X=~5lEz|ejQjwm~a+AAk<-o0aO1=5;b${ppZ=VluPg zY_H9XSHk9dtx_+@xQ|9)->W9Hg=YOa1%$iklFRm&dC%MNYuny~ZowCf%(J64!7 zTxH($%k&1*Z+kw)1;K6?x7B5@FTcmt-Y|Q=@uvxSFK$e0J|~=cdRgSmJFi~&+|+b? zKFip1nfSFdg_QG2mOH8s6n}p3z-9MgF1Hhsd7pC>-ds<2`*Wk?lh&!`kO+yj#~v; zI5!D=Ykz+8K*#hKU&O;UOkey!c=P$U)i?TY3N7L|XLrVa>Q2L+vrp~k`1tWm`Jq&m z6QU&9cgV*jXi8?c+_8#!L+%3iEw2~;W;PGpeo|A|?Z;%vrEBLht(m*v!ef&({u!%n u7{u*9t-1V6MZV(x+n96TR{xyOyq_^Wg&}c Date: Wed, 26 Dec 2012 17:33:48 -0600 Subject: [PATCH 19/39] Removed unnecessary regex in code block plugin --- plugins/code_block.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/code_block.rb b/plugins/code_block.rb index 62c551a..660f73d 100644 --- a/plugins/code_block.rb +++ b/plugins/code_block.rb @@ -50,7 +50,6 @@ module Jekyll include HighlightCode include TemplateWrapper CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/i - CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/\S+|\/\S+)/i Caption = /(\S[\S\s]*)/ def initialize(tag_name, markup, tokens) @title = nil @@ -63,10 +62,7 @@ module Jekyll end if markup =~ CaptionUrlTitle @file = $1 - @caption = "
    #{$1}#{$3}
    " - elsif markup =~ CaptionUrl - @file = $1 - @caption = "
    #{$1}link
    " + @caption = "
    #{$1}#{$3 || 'link'}
    " elsif markup =~ Caption @file = $1 @caption = "
    #{$1}
    \n" From e179277e40d789bddc514782cda6bb3b2c1c86cd Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Sat, 29 Dec 2012 02:15:19 -0600 Subject: [PATCH 20/39] updated gems --- Gemfile | 12 ++++++------ Gemfile.lock | 41 ++++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/Gemfile b/Gemfile index be2518b..f378954 100644 --- a/Gemfile +++ b/Gemfile @@ -1,18 +1,18 @@ source "http://rubygems.org" group :development do - gem 'rake', '~> 0.9.2' + gem 'rake', '~> 0.9' gem 'rack', '~> 1.4.1' - gem 'jekyll', '~> 0.11.2' + gem 'jekyll', '~> 0.12' gem 'rdiscount', '~> 1.6.8' - gem 'pygments.rb', '~> 0.2.12' + gem 'pygments.rb', '~> 0.3.4' gem 'RedCloth', '~> 4.2.9' - gem 'haml', '~> 3.1.6' - gem 'compass', '~> 0.12.1' + gem 'haml', '~> 3.1.7' + gem 'compass', '~> 0.12.2' gem 'rubypants', '~> 0.2.0' gem 'rb-fsevent', '~> 0.9' gem 'stringex', '~> 1.4.0' gem 'liquid', '~> 2.3.0' end -gem 'sinatra', '~> 1.3.2' +gem 'sinatra', '~> 1.3.3' diff --git a/Gemfile.lock b/Gemfile.lock index 5060be1..c235b2c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,9 +2,6 @@ GEM remote: http://rubygems.org/ specs: RedCloth (4.2.9) - albino (1.3.3) - posix-spawn (>= 0.3.6) - blankslate (2.1.2.4) chunky_png (1.2.5) classifier (1.3.3) fast-stemmer (>= 1.0.0) @@ -14,56 +11,54 @@ GEM sass (~> 3.1) directory_watcher (1.4.1) fast-stemmer (1.0.1) - ffi (1.0.11) fssm (0.2.9) - haml (3.1.6) - jekyll (0.11.2) - albino (~> 1.3) + haml (3.1.7) + jekyll (0.12.0) classifier (~> 1.3) directory_watcher (~> 1.1) - kramdown (~> 0.13) + kramdown (~> 0.13.4) liquid (~> 2.3) maruku (~> 0.5) - kramdown (0.13.7) + pygments.rb (~> 0.3.2) + kramdown (0.13.8) liquid (2.3.0) - maruku (0.6.0) + maruku (0.6.1) syntax (>= 1.0.0) posix-spawn (0.3.6) - pygments.rb (0.2.13) - rubypython (~> 0.5.3) + pygments.rb (0.3.4) + posix-spawn (~> 0.3.6) + yajl-ruby (~> 1.1.0) rack (1.4.1) - rack-protection (1.2.0) + rack-protection (1.3.2) rack rake (0.9.2.2) rb-fsevent (0.9.1) rdiscount (1.6.8) rubypants (0.2.0) - rubypython (0.5.3) - blankslate (>= 2.1.2.3) - ffi (~> 1.0.7) sass (3.1.20) - sinatra (1.3.2) + sinatra (1.3.3) rack (~> 1.3, >= 1.3.6) rack-protection (~> 1.2) tilt (~> 1.3, >= 1.3.3) stringex (1.4.0) syntax (1.0.0) tilt (1.3.3) + yajl-ruby (1.1.0) PLATFORMS ruby DEPENDENCIES RedCloth (~> 4.2.9) - compass (~> 0.12.1) - haml (~> 3.1.6) - jekyll (~> 0.11.2) + compass (~> 0.12.2) + haml (~> 3.1.7) + jekyll (~> 0.12) liquid (~> 2.3.0) - pygments.rb (~> 0.2.12) + pygments.rb (~> 0.3.4) rack (~> 1.4.1) - rake (~> 0.9.2) + rake (~> 0.9) rb-fsevent (~> 0.9) rdiscount (~> 1.6.8) rubypants (~> 0.2.0) - sinatra (~> 1.3.2) + sinatra (~> 1.3.3) stringex (~> 1.4.0) From 65f7f7f0b3fa2264336d21a169b7ef426079dd2d Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Tue, 1 Jan 2013 14:22:48 -0600 Subject: [PATCH 21/39] Rake task new_post now accepts titles through stdin This should help resolve issues for zsh users and make it easier to enter titles which freak out Rake's argument processing --- Rakefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index ef9af47..6c699df 100644 --- a/Rakefile +++ b/Rakefile @@ -92,10 +92,13 @@ end # usage rake new_post[my-new-post] or rake new_post['my new post'] or rake new_post (defaults to "new-post") desc "Begin a new post in #{source_dir}/#{posts_dir}" task :new_post, :title do |t, args| + if args.title + title = args.title + else + title = get_stdin("Enter a title for your post: ") + end raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir) mkdir_p "#{source_dir}/#{posts_dir}" - args.with_defaults(:title => 'new-post') - title = args.title filename = "#{source_dir}/#{posts_dir}/#{Time.now.strftime('%Y-%m-%d')}-#{title.to_url}.#{new_post_ext}" if File.exist?(filename) abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n' From c814560c86917f2931c90610e7c5343bbe63b3b6 Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Wed, 2 Jan 2013 21:02:50 -0600 Subject: [PATCH 22/39] removed accidentally added file --- source/images/icon-sdc231d6676.png | Bin 1513 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 source/images/icon-sdc231d6676.png diff --git a/source/images/icon-sdc231d6676.png b/source/images/icon-sdc231d6676.png deleted file mode 100644 index 38ef928f78e5684b25350ca827535045008ae8bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1513 zcmeAS@N?(olHy`uVBq!ia0vp^3P7B|!3-q5|1_*(U|?Jx;1l8sKxN$%wN(#wXC5}*@!D+9 zTk|#7t+zk5U2xQQ-{{G!rwD(YGW#+Ej&fl;vu$(cF%6^+y8FI};E-Ns#qkDWYo z{?hG-PdEaktaqH|f zdmrIInd9~E@9o|FTK?ab2nW_V9x^mv~(qjKcr)eRPsa~25j_%85TTK>JN{N7jj>)&h(E_k%>K3zS(=6Ch}_wT>&7JfKo z{*U+u#+eKev!*df7){GfaEK~-Z$D+OcF+>Xi3hyh9VfNL9+?nRBT&OI^WP3$4h7zH zVbueVg^W`|dK?cid$(?Ne8Oaq;^mn1e}k0%nw_FXoa_rKJtoNo&RSv9zxO@EuAm93 zEON6&9TrVse|aK2N{}UNQOZH5Gb*!O4+z}&ogl*4Taa@?v~g)-C+~$xk=;3mI;P*f z;xkjQtt`hpFe1I8m?uN0Q91me%Ddm$9JwcB15ek=1$9cS*Yeh5{A(BUFgeus+i9Uy zpLX)tY_L5fn#%Ahdwb-rpsCAZ%61+)yJM~XG*O>bN3(w&ihFtZM&CiBGZxDWh0@nl zu5NrWrMSP&@W@mRAHxR!^6)pmkIz4`XX~wFK?dek>wRs1#-y81x^Rlg$z^0|L! z3zs>S{GIEzhoSNH8!@p~X=~5lEz|ejQjwm~a+AAk<-o0aO1=5;b${ppZ=VluPg zY_H9XSHk9dtx_+@xQ|9)->W9Hg=YOa1%$iklFRm&dC%MNYuny~ZowCf%(J64!7 zTxH($%k&1*Z+kw)1;K6?x7B5@FTcmt-Y|Q=@uvxSFK$e0J|~=cdRgSmJFi~&+|+b? zKFip1nfSFdg_QG2mOH8s6n}p3z-9MgF1Hhsd7pC>-ds<2`*Wk?lh&!`kO+yj#~v; zI5!D=Ykz+8K*#hKU&O;UOkey!c=P$U)i?TY3N7L|XLrVa>Q2L+vrp~k`1tWm`Jq&m z6QU&9cgV*jXi8?c+_8#!L+%3iEw2~;W;PGpeo|A|?Z;%vrEBLht(m*v!ef&({u!%n u7{u*9t-1V6MZV(x+n96TR{xyOyq_^Wg&}c Date: Wed, 2 Jan 2013 20:55:09 -0800 Subject: [PATCH 23/39] Escape github repo descriptions, as they may contain HTML. --- .themes/classic/source/javascripts/github.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.themes/classic/source/javascripts/github.js b/.themes/classic/source/javascripts/github.js index 9e98b8c..27a5a23 100644 --- a/.themes/classic/source/javascripts/github.js +++ b/.themes/classic/source/javascripts/github.js @@ -1,9 +1,12 @@ var github = (function(){ + function escapeHtml(str) { + return $('
    ').text(str).html(); + } function render(target, repos){ var i = 0, fragment = '', t = $(target)[0]; for(i = 0; i < repos.length; i++) { - fragment += '
  • '+repos[i].name+'

    '+(repos[i].description||'')+'

  • '; + fragment += '
  • '+repos[i].name+'

    '+escapeHtml(repos[i].description||'')+'

  • '; } t.innerHTML = fragment; } From 9decd23b5a7a2f26590a4995cafcba010695717d Mon Sep 17 00:00:00 2001 From: Brandon Mathis Date: Sun, 6 Jan 2013 22:52:54 -0600 Subject: [PATCH 24/39] updated ender.js to latest --- .themes/classic/source/javascripts/ender.js | 34 +- .../classic/source/javascripts/libs/ender.js | 4611 ++++++++++++----- 2 files changed, 3202 insertions(+), 1443 deletions(-) diff --git a/.themes/classic/source/javascripts/ender.js b/.themes/classic/source/javascripts/ender.js index 1add349..6d9c66e 100644 --- a/.themes/classic/source/javascripts/ender.js +++ b/.themes/classic/source/javascripts/ender.js @@ -8,38 +8,38 @@ /*! * Ender: open module JavaScript framework (client-lib) - * copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat) - * http://ender.no.de + * copyright Dustin Diaz & Jacob Thornton 2011-2012 (@ded @fat) + * http://ender.jit.su * License MIT */ -!function(a){function d(a){var c=b[a]||window[a];if(!c)throw new Error("Requested module '"+a+"' has not been defined.");return c}function e(a,c){return b[a]=c}function f(a,b){for(var c in b)c!="noConflict"&&c!="_VERSION"&&(a[c]=b[c]);return a}function g(a,b,c){return h._select&&(typeof a=="string"||a.nodeName||a.length&&"item"in a||a==window)?(c=h._select(a,b),c.selector=a):c=isFinite(a.length)?a:[a],f(c,g)}function h(a,b){return g(a,b)}a.global=a;var b={},c=a.$;a.provide=e,a.require=d,f(h,{_VERSION:"0.3.4",fn:a.$&&a.$.fn||{},ender:function(a,b){f(b?g:h,a)},_select:function(a,b){return(b||document).querySelectorAll(a)}}),f(g,{forEach:function(a,b,c){for(c=0,l=this.length;c0?this:[]).concat(Array.prototype.slice.call(arguments,0));return b[a].apply(null,c)}},d=c("serialize"),e=c("serializeArray");a.ender({ajax:b,serialize:d,serializeArray:e,toQueryString:b.toQueryString}),a.ender({serialize:d,serializeArray:e},!0)}(ender)}(),!function(){var a={exports:{}},b=a.exports; +;!function(name,definition){typeof module!="undefined"?module.exports=definition():typeof define=="function"&&define.amd?define(definition):this[name]=definition()}("reqwest",function(){function handleReadyState(o,success,error){return function(){o&&o[readyState]==4&&(twoHundo.test(o.status)?success(o):error(o))}}function setHeaders(http,o){var headers=o.headers||{},h;headers.Accept=headers.Accept||defaultHeaders.accept[o.type]||defaultHeaders.accept["*"];!o.crossOrigin&&!headers[requestedWith]&&(headers[requestedWith]=defaultHeaders.requestedWith);headers[contentType]||(headers[contentType]=o.contentType||defaultHeaders.contentType);for(h in headers)headers.hasOwnProperty(h)&&http.setRequestHeader(h,headers[h])}function setCredentials(http,o){typeof o.withCredentials!="undefined"&&typeof http.withCredentials!="undefined"&&(http.withCredentials=!!o.withCredentials)}function generalCallback(data){lastValue=data}function urlappend(url,s){return url+(/\?/.test(url)?"&":"?")+s}function handleJsonp(o,fn,err,url){var reqId=uniqid++,cbkey=o.jsonpCallback||"callback",cbval=o.jsonpCallbackName||reqwest.getcallbackPrefix(reqId),cbreg=new RegExp("((^|\\?|&)"+cbkey+")=([^&]+)"),match=url.match(cbreg),script=doc.createElement("script"),loaded=0;match?match[3]==="?"?url=url.replace(cbreg,"$1="+cbval):cbval=match[3]:url=urlappend(url,cbkey+"="+cbval);win[cbval]=generalCallback;script.type="text/javascript";script.src=url;script.async=!0;if(typeof script.onreadystatechange!="undefined"){script.event="onclick";script.htmlFor=script.id="_reqwest_"+reqId}script.onload=script.onreadystatechange=function(){if(script[readyState]&&script[readyState]!=="complete"&&script[readyState]!=="loaded"||loaded)return!1;script.onload=script.onreadystatechange=null;script.onclick&&script.onclick();o.success&&o.success(lastValue);lastValue=undefined;head.removeChild(script);loaded=1};head.appendChild(script)}function getRequest(o,fn,err){var method=(o.method||"GET").toUpperCase(),url=typeof o=="string"?o:o.url,data=o.processData!==!1&&o.data&&typeof o.data!="string"?reqwest.toQueryString(o.data):o.data||null,http;if((o.type=="jsonp"||method=="GET")&&data){url=urlappend(url,data);data=null}if(o.type=="jsonp")return handleJsonp(o,fn,err,url);http=xhr();http.open(method,url,!0);setHeaders(http,o);setCredentials(http,o);http.onreadystatechange=handleReadyState(http,fn,err);o.before&&o.before(http);http.send(data);return http}function Reqwest(o,fn){this.o=o;this.fn=fn;init.apply(this,arguments)}function setType(url){var m=url.match(/\.(json|jsonp|html|xml)(\?|$)/);return m?m[1]:"js"}function init(o,fn){function complete(resp){o.timeout&&clearTimeout(self.timeout);self.timeout=null;while(self._completeHandlers.length>0)self._completeHandlers.shift()(resp)}function success(resp){var r=resp.responseText;if(r)switch(type){case"json":try{resp=win.JSON?win.JSON.parse(r):eval("("+r+")")}catch(err){return error(resp,"Could not parse JSON in response",err)}break;case"js":resp=eval(r);break;case"html":resp=r;break;case"xml":resp=resp.responseXML}self._responseArgs.resp=resp;self._fulfilled=!0;fn(resp);while(self._fulfillmentHandlers.length>0)self._fulfillmentHandlers.shift()(resp);complete(resp)}function error(resp,msg,t){self._responseArgs.resp=resp;self._responseArgs.msg=msg;self._responseArgs.t=t;self._erred=!0;while(self._errorHandlers.length>0)self._errorHandlers.shift()(resp,msg,t);complete(resp)}this.url=typeof o=="string"?o:o.url;this.timeout=null;this._fulfilled=!1;this._fulfillmentHandlers=[];this._errorHandlers=[];this._completeHandlers=[];this._erred=!1;this._responseArgs={};var self=this,type=o.type||setType(this.url);fn=fn||function(){};o.timeout&&(this.timeout=setTimeout(function(){self.abort()},o.timeout));o.success&&this._fulfillmentHandlers.push(function(){o.success.apply(o,arguments)});o.error&&this._errorHandlers.push(function(){o.error.apply(o,arguments)});o.complete&&this._completeHandlers.push(function(){o.complete.apply(o,arguments)});this.request=getRequest(o,success,error)}function reqwest(o,fn){return new Reqwest(o,fn)}function normalize(s){return s?s.replace(/\r?\n/g,"\r\n"):""}function serial(el,cb){var n=el.name,t=el.tagName.toLowerCase(),optCb=function(o){o&&!o.disabled&&cb(n,normalize(o.attributes.value&&o.attributes.value.specified?o.value:o.text))};if(el.disabled||!n)return;switch(t){case"input":if(!/reset|button|image|file/i.test(el.type)){var ch=/checkbox/i.test(el.type),ra=/radio/i.test(el.type),val=el.value;(!ch&&!ra||el.checked)&&cb(n,normalize(ch&&val===""?"on":val))}break;case"textarea":cb(n,normalize(el.value));break;case"select":if(el.type.toLowerCase()==="select-one")optCb(el.selectedIndex>=0?el.options[el.selectedIndex]:null);else for(var i=0;el.length&&i0){typeSpec=str2arr(typeSpec);for(i=typeSpec.length;i--;)off(element,typeSpec[i],fn);return element}type=isTypeStr&&typeSpec.replace(nameRegex,"");type&&customEvents[type]&&(type=customEvents[type].base);if(!typeSpec||isTypeStr){if(namespaces=isTypeStr&&typeSpec.replace(namespaceRegex,""))namespaces=str2arr(namespaces,".");removeListener(element,type,fn,namespaces)}else if(isFunction(typeSpec))removeListener(element,null,typeSpec);else for(k in typeSpec)typeSpec.hasOwnProperty(k)&&off(element,k,typeSpec[k]);return element},on=function(element,events,selector,fn){var originalFn,type,types,i,args,entry,first;if(selector===undefined&&typeof events=="object"){for(type in events)events.hasOwnProperty(type)&&on.call(this,element,type,events[type]);return}if(!isFunction(selector)){originalFn=fn;args=slice.call(arguments,4);fn=delegate(selector,originalFn,selectorEngine)}else{args=slice.call(arguments,3);fn=originalFn=selector}types=str2arr(events);this===ONE&&(fn=once(off,element,events,fn,originalFn));for(i=types.length;i--;){first=registry.put(entry=new RegEntry(element,types[i].replace(nameRegex,""),fn,originalFn,str2arr(types[i].replace(namespaceRegex,""),"."),args,!1));entry[eventSupport]&&first&&listener(element,entry.eventType,!0,entry.customType)}return element},add=function(element,events,fn,delfn){return on.apply(null,isString(fn)?[element,fn,events,delfn].concat(arguments.length>3?slice.call(arguments,5):[]):slice.call(arguments))},one=function(){return on.apply(ONE,arguments)},fire=function(element,type,args){var types=str2arr(type),i,j,l,names,handlers;for(i=types.length;i--;){type=types[i].replace(nameRegex,"");if(names=types[i].replace(namespaceRegex,""))names=str2arr(names,".");if(!names&&!args&&element[eventSupport])fireListener(nativeEvents[type],type,element);else{handlers=registry.get(element,type,null,!1);args=[!1].concat(args);for(j=0,l=handlers.length;j]+)/.exec(a),d=c.createElement(b&&k[b[1].toLowerCase()]||"div"),e=[];d.innerHTML=a;var f=d.childNodes;d=d.firstChild,e.push(d);while(d=d.nextSibling)d.nodeType==1&&e.push(d);return e}():A(a)?[a.cloneNode(!0)]:[]},N.doc=function(){var a=this.viewport();return{width:Math.max(c.body.scrollWidth,d.scrollWidth,a.width),height:Math.max(c.body.scrollHeight,d.scrollHeight,a.height)}},N.firstChild=function(a){for(var b=a.childNodes,c=0,d=b&&b.length||0,e;c0?cloneNode(self,el):el)},null,rev)},this,rev);self.length=i;each(r,function(e){self[--i]=e},null,!rev);return self}function xy(el,x,y){var $el=bonzo(el),style=$el.css("position"),offset=$el.offset(),rel="relative",isRel=style==rel,delta=[parseInt($el.css("left"),10),parseInt($el.css("top"),10)];if(style=="static"){$el.css("position",rel);style=rel}isNaN(delta[0])&&(delta[0]=isRel?0:el.offsetLeft);isNaN(delta[1])&&(delta[1]=isRel?0:el.offsetTop);x!=null&&(el.style.left=x-offset.left+delta[0]+px);y!=null&&(el.style.top=y-offset.top+delta[1]+px)}function setter(el,v){return typeof v=="function"?v(el):v}function Bonzo(elements){this.length=0;if(elements){elements=typeof elements!="string"&&!elements.nodeType&&typeof elements.length!="undefined"?elements:[elements];this.length=elements.length;for(var i=0;i/,table=["","
    ",1],td=["","
    ",3],option=["",1],noscope=["_","",0,1],tagMap={thead:table,tbody:table,tfoot:table,colgroup:table,caption:table,tr:["","
    ",2],th:td,td:td,col:["","
    ",2],fieldset:["
    ","
    ",1],legend:["
    ","
    ",2],option:option,optgroup:option,script:noscope,style:noscope,link:noscope,param:noscope,base:noscope},stateAttributes=/^(checked|selected|disabled)$/,ie=/msie/i.test(navigator.userAgent),hasClass,addClass,removeClass,uidMap={},uuids=0,digit=/^-?[\d\.]+$/,dattr=/^data-(.+)$/,px="px",setAttribute="setAttribute",getAttribute="getAttribute",byTag="getElementsByTagName",features=function(){var e=doc.createElement("p");e.innerHTML='x
    ';return{hrefExtended:e[byTag]("a")[0][getAttribute]("href")!="#x",autoTbody:e[byTag]("tbody").length!==0,computedStyle:doc.defaultView&&doc.defaultView.getComputedStyle,cssFloat:e[byTag]("table")[0].style.styleFloat?"styleFloat":"cssFloat",transform:function(){var props=["transform","webkitTransform","MozTransform","OTransform","msTransform"],i;for(i=0;i]+)/),el=doc.createElement("div"),els=[],p=tag?tagMap[tag[1].toLowerCase()]:null,dep=p?p[2]+1:1,ns=p&&p[3],pn=parentNode,tb=features.autoTbody&&p&&p[0]==""&&!/])\s*/g,C=/[\s\>\+\~]/,D=/(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\]|[\s\w\+\-]*\))/,E=/([.*+?\^=!:${}()|\[\]\/\\])/g,F=/^([a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/,G=/\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/,H=/:([\w\-]+)(\(['"]?([\s\w\+\-]+)['"]?\))?/,I=new RegExp("("+C.source+")"+D.source,"g"),J=new RegExp(C.source+D.source),K=new RegExp(F.source+"("+G.source+")?"+"("+H.source+")?"),L={" ":function(a){return a&&a!==u&&a.parentNode},">":function(a,b){return a&&a.parentNode==b.parentNode&&a.parentNode},"~":function(a){return a&&a.previousSibling},"+":function(a,b,c,d){return a?(c=S(a),d=S(b),c&&d&&c==d&&c):!1}};M.prototype={g:function(a){return this.c[a]||undefined},s:function(a,b){return this.c[a]=b,b}};var N=new M,O=new M,P=new M,Q=new M,bb="compareDocumentPosition"in u?function(a,b){return(b.compareDocumentPosition(a)&16)==16}:"contains"in u?function(a,c){return c=c==b||c==window?u:c,c!==a&&c.contains(a)}:function(a,b){while(a=a.parentNode)if(a===b)return 1;return 0},bc=function(){if(!b.querySelector||!b.querySelectorAll)return!1;try{return b.querySelectorAll(":nth-of-type(1)").length}catch(a){return!1}}(),bd=bc?function(a,c){return b.getElementsByClassName&&(i=a.match(y))?R(c.getElementsByClassName(i[1])):R(c.querySelectorAll(a))}:function(a,c){a=a.replace(B,"$1");var d=[],e,g,j=[],k;if(i=a.match(A)){s=c.getElementsByTagName(i[1]||"*"),l=N.g(i[2])||N.s(i[2],new RegExp("(^|\\s+)"+i[2]+"(\\s+|$)"));for(k=0,h=s.length,f=0;k]+)\s*/.exec(b)[1],f=(c||a).createElement(e[d]||"div"),g=[];f.innerHTML=b;var h=f.childNodes;f=f.firstChild,f.nodeType==1&&g.push(f);while(f=f.nextSibling)f.nodeType==1&&g.push(f);return g}var c=require("qwery"),d="table",e={thead:d,tbody:d,tfoot:d,tr:"tbody",th:"tr",td:"tr",fieldset:"form",option:"select"};b._select=function(a,b){return/^\s*~+]/,normalizr=/^\s+|\s*([,\s\+\~>]|$)\s*/g,splitters=/[\s\>\+\~]/,splittersMore=/(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\]|[\s\w\+\-]*\))/,specialChars=/([.*+?\^=!:${}()|\[\]\/\\])/g,simple=/^(\*|[a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/,attr=/\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/,pseudo=/:([\w\-]+)(\(['"]?([^()]+)['"]?\))?/,easy=new RegExp(idOnly.source+"|"+tagOnly.source+"|"+classOnly.source),dividers=new RegExp("("+splitters.source+")"+splittersMore.source,"g"),tokenizr=new RegExp(splitters.source+splittersMore.source),chunker=new RegExp(simple.source+"("+attr.source+")?"+"("+pseudo.source+")?"),walker={" ":function(node){return node&&node!==html&&node.parentNode},">":function(node,contestant){return node&&node.parentNode==contestant.parentNode&&node.parentNode},"~":function(node){return node&&node.previousSibling},"+":function(node,contestant,p1,p2){return node?(p1=previous(node))&&(p2=previous(contestant))&&p1==p2&&p1:!1}};cache.prototype={g:function(k){return this.c[k]||undefined},s:function(k,v,r){v=r?new RegExp(v):v;return this.c[k]=v}};var classCache=new cache,cleanCache=new cache,attrCache=new cache,tokenCache=new cache,isAncestor="compareDocumentPosition"in html?function(element,container){return(container.compareDocumentPosition(element)&16)==16}:"contains"in html?function(element,container){container=container[nodeType]===9||container==window?html:container;return container!==element&&container.contains(element)}:function(element,container){while(element=element.parentNode)if(element===container)return 1;return 0},getAttr=function(){var e=doc.createElement("p");return(e.innerHTML='x')&&e.firstChild.getAttribute("href")!="#x"?function(e,a){return a==="class"?e.className:a==="href"||a==="src"?e.getAttribute(a,2):e.getAttribute(a)}:function(e,a){return e.getAttribute(a)}}(),hasByClass=!!doc[byClass],hasQSA=doc.querySelector&&doc[qSA],selectQSA=function(selector,root){var result=[],ss,e;try{if(root[nodeType]===9||!splittable.test(selector))return arrayify(root[qSA](selector));each(ss=selector.split(","),collectSelector(root,function(ctx,s){e=ctx[qSA](s);e.length==1?result[result.length]=e.item(0):e.length&&(result=result.concat(arrayify(e)))}));return ss.length>1&&result.length>1?uniq(result):result}catch(ex){}return selectNonNative(selector,root)},selectNonNative=function(selector,root){var result=[],items,m,i,l,r,ss;selector=selector.replace(normalizr,"$1");if(m=selector.match(tagAndOrClass)){r=classRegex(m[2]);items=root[byTag](m[1]||"*");for(i=0,l=items.length;i1&&result.length>1?uniq(result):result},configure=function(options){typeof options[useNativeQSA]!="undefined"&&(select=options[useNativeQSA]?hasQSA?selectQSA:selectNonNative:selectNonNative)};configure({useNativeQSA:!0});qwery.configure=configure;qwery.uniq=uniq;qwery.is=is;qwery.pseudos={};return qwery});provide("qwery",module.exports);(function($){var q=function(){var r;try{r=require("qwery")}catch(ex){r=require("qwery-mobile")}finally{return r}}();$.pseudos=q.pseudos;$._select=function(s,r){return($._select=function(){var b;if(typeof $.create=="function")return function(s,r){return/^\s*.+?<\\/" + t + ">", "g")); - each(bitches, function (m) { - m = m.replace(/<(.+)>(.+?)<\/\1>/, '$2'); - var bah = doc.createElement(t); - bah.appendChild(doc.createDocumentFragment(m)); - el.appendChild(bah); - }); + return new XMLHttpRequest() + } : + function () { + return new ActiveXObject('Microsoft.XMLHTTP') + } + + function handleReadyState(o, success, error) { + return function () { + if (o && o[readyState] == 4) { + if (twoHundo.test(o.status)) { + success(o) + } else { + error(o) + } + } + } + } + + function setHeaders(http, o) { + var headers = o.headers || {}, h + headers.Accept = headers.Accept || defaultHeaders.accept[o.type] || defaultHeaders.accept['*'] + // breaks cross-origin requests with legacy browsers + if (!o.crossOrigin && !headers[requestedWith]) headers[requestedWith] = defaultHeaders.requestedWith + if (!headers[contentType]) headers[contentType] = o.contentType || defaultHeaders.contentType + for (h in headers) { + headers.hasOwnProperty(h) && http.setRequestHeader(h, headers[h]) + } + } + + function setCredentials(http, o) { + if (typeof o.withCredentials !== "undefined" && typeof http.withCredentials !== "undefined") { + http.withCredentials = !!o.withCredentials + } + } + + function generalCallback(data) { + lastValue = data + } + + function urlappend(url, s) { + return url + (/\?/.test(url) ? '&' : '?') + s + } + + function handleJsonp(o, fn, err, url) { + var reqId = uniqid++ + , cbkey = o.jsonpCallback || 'callback' // the 'callback' key + , cbval = o.jsonpCallbackName || reqwest.getcallbackPrefix(reqId) + // , cbval = o.jsonpCallbackName || ('reqwest_' + reqId) // the 'callback' value + , cbreg = new RegExp('((^|\\?|&)' + cbkey + ')=([^&]+)') + , match = url.match(cbreg) + , script = doc.createElement('script') + , loaded = 0 + + if (match) { + if (match[3] === '?') { + url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name } else { - el.innerHTML = node; + cbval = match[3] // provided callback func name } - var nodes = el.childNodes; - el = el.firstChild; - els.push(el); - while (el = el.nextSibling) { - (el.nodeType == 1) && els.push(el); - } - return els; - - }() : is(node) ? [node.cloneNode(true)] : []; - }; - - bonzo.doc = function () { - var w = html.scrollWidth, - h = html.scrollHeight, - vp = this.viewport(); - return { - width: Math.max(w, vp.width), - height: Math.max(h, vp.height) - }; - }; - - bonzo.firstChild = function (el) { - for (var c = el.childNodes, i = 0, j = (c && c.length) || 0, e; i < j; i++) { - if (c[i].nodeType === 1) { - e = c[j = i]; + } else { + url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em } + + win[cbval] = generalCallback + + script.type = 'text/javascript' + script.src = url + script.async = true + if (typeof script.onreadystatechange !== 'undefined') { + // need this for IE due to out-of-order onreadystatechange(), binding script + // execution to an event listener gives us control over when the script + // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html + script.event = 'onclick' + script.htmlFor = script.id = '_reqwest_' + reqId + } + + script.onload = script.onreadystatechange = function () { + if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) { + return false + } + script.onload = script.onreadystatechange = null + script.onclick && script.onclick() + // Call the user callback with the last value stored and clean up values and scripts. + o.success && o.success(lastValue) + lastValue = undefined + head.removeChild(script) + loaded = 1 + } + + // Add the script to the DOM head + head.appendChild(script) } - return e; - }; - - bonzo.viewport = function () { - var h = self.innerHeight, - w = self.innerWidth; - ie && (h = html.clientHeight) && (w = html.clientWidth); - return { - width: w, - height: h - }; - }; - - bonzo.isAncestor = 'compareDocumentPosition' in html ? - function (container, element) { - return (container.compareDocumentPosition(element) & 16) == 16; - } : 'contains' in html ? - function (container, element) { - return container !== element && container.contains(element); - } : - function (container, element) { - while (element = element.parentNode) { - if (element === container) { - return true; + + function getRequest(o, fn, err) { + var method = (o.method || 'GET').toUpperCase() + , url = typeof o === 'string' ? o : o.url + // convert non-string objects to query-string form unless o.processData is false + , data = (o.processData !== false && o.data && typeof o.data !== 'string') + ? reqwest.toQueryString(o.data) + : (o.data || null) + , http + + // if we're working on a GET request and we have data then we should append + // query string to end of URL and not post data + if ((o.type == 'jsonp' || method == 'GET') && data) { + url = urlappend(url, data) + data = null + } + + if (o.type == 'jsonp') return handleJsonp(o, fn, err, url) + + http = xhr() + http.open(method, url, true) + setHeaders(http, o) + setCredentials(http, o) + http.onreadystatechange = handleReadyState(http, fn, err) + o.before && o.before(http) + http.send(data) + return http + } + + function Reqwest(o, fn) { + this.o = o + this.fn = fn + + init.apply(this, arguments) + } + + function setType(url) { + var m = url.match(/\.(json|jsonp|html|xml)(\?|$)/) + return m ? m[1] : 'js' + } + + function init(o, fn) { + + this.url = typeof o == 'string' ? o : o.url + this.timeout = null + + // whether request has been fulfilled for purpose + // of tracking the Promises + this._fulfilled = false + // success handlers + this._fulfillmentHandlers = [] + // error handlers + this._errorHandlers = [] + // complete (both success and fail) handlers + this._completeHandlers = [] + this._erred = false + this._responseArgs = {} + + var self = this + , type = o.type || setType(this.url) + + fn = fn || function () {} + + if (o.timeout) { + this.timeout = setTimeout(function () { + self.abort() + }, o.timeout) + } + + if (o.success) { + this._fulfillmentHandlers.push(function () { + o.success.apply(o, arguments) + }) + } + + if (o.error) { + this._errorHandlers.push(function () { + o.error.apply(o, arguments) + }) + } + + if (o.complete) { + this._completeHandlers.push(function () { + o.complete.apply(o, arguments) + }) + } + + function complete(resp) { + o.timeout && clearTimeout(self.timeout) + self.timeout = null + while (self._completeHandlers.length > 0) { + self._completeHandlers.shift()(resp) } } - return false; - }; - - var old = context.bonzo; - bonzo.noConflict = function () { - context.bonzo = old; - return this; - }; - context['bonzo'] = bonzo; - -}(this);!function ($) { - - var b = bonzo; - b.setQueryEngine($); - $.ender(b); - $.ender(b(), true); - $.ender({ - create: function (node) { - return $(b.create(node)); + + function success(resp) { + var r = resp.responseText + if (r) { + switch (type) { + case 'json': + try { + resp = win.JSON ? win.JSON.parse(r) : eval('(' + r + ')') + } catch (err) { + return error(resp, 'Could not parse JSON in response', err) + } + break; + case 'js': + resp = eval(r) + break; + case 'html': + resp = r + break; + case 'xml': + resp = resp.responseXML; + break; + } + } + + self._responseArgs.resp = resp + self._fulfilled = true + fn(resp) + while (self._fulfillmentHandlers.length > 0) { + self._fulfillmentHandlers.shift()(resp) + } + + complete(resp) + } + + function error(resp, msg, t) { + self._responseArgs.resp = resp + self._responseArgs.msg = msg + self._responseArgs.t = t + self._erred = true + while (self._errorHandlers.length > 0) { + self._errorHandlers.shift()(resp, msg, t) + } + complete(resp) + } + + this.request = getRequest(o, success, error) } + + Reqwest.prototype = { + abort: function () { + this.request.abort() + } + + , retry: function () { + init.call(this, this.o, this.fn) + } + + /** + * Small deviation from the Promises A CommonJs specification + * http://wiki.commonjs.org/wiki/Promises/A + */ + + /** + * `then` will execute upon successful requests + */ + , then: function (success, fail) { + if (this._fulfilled) { + success(this._responseArgs.resp) + } else if (this._erred) { + fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t) + } else { + this._fulfillmentHandlers.push(success) + this._errorHandlers.push(fail) + } + return this + } + + /** + * `always` will execute whether the request succeeds or fails + */ + , always: function (fn) { + if (this._fulfilled || this._erred) { + fn(this._responseArgs.resp) + } else { + this._completeHandlers.push(fn) + } + return this + } + + /** + * `fail` will execute when the request fails + */ + , fail: function (fn) { + if (this._erred) { + fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t) + } else { + this._errorHandlers.push(fn) + } + return this + } + } + + function reqwest(o, fn) { + return new Reqwest(o, fn) + } + + // normalize newline variants according to spec -> CRLF + function normalize(s) { + return s ? s.replace(/\r?\n/g, '\r\n') : '' + } + + function serial(el, cb) { + var n = el.name + , t = el.tagName.toLowerCase() + , optCb = function (o) { + // IE gives value="" even where there is no value attribute + // 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273 + if (o && !o.disabled) + cb(n, normalize(o.attributes.value && o.attributes.value.specified ? o.value : o.text)) + } + + // don't serialize elements that are disabled or without a name + if (el.disabled || !n) return; + + switch (t) { + case 'input': + if (!/reset|button|image|file/i.test(el.type)) { + var ch = /checkbox/i.test(el.type) + , ra = /radio/i.test(el.type) + , val = el.value; + // WebKit gives us "" instead of "on" if a checkbox has no value, so correct it here + (!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val)) + } + break; + case 'textarea': + cb(n, normalize(el.value)) + break; + case 'select': + if (el.type.toLowerCase() === 'select-one') { + optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null) + } else { + for (var i = 0; el.length && i < el.length; i++) { + el.options[i].selected && optCb(el.options[i]) + } + } + break; + } + } + + // collect up all form elements found from the passed argument elements all + // the way down to child elements; pass a '
    ' or form fields. + // called with 'this'=callback to use for serial() on each element + function eachFormElement() { + var cb = this + , e, i, j + , serializeSubtags = function (e, tags) { + for (var i = 0; i < tags.length; i++) { + var fa = e[byTag](tags[i]) + for (j = 0; j < fa.length; j++) serial(fa[j], cb) + } + } + + for (i = 0; i < arguments.length; i++) { + e = arguments[i] + if (/input|select|textarea/i.test(e.tagName)) serial(e, cb) + serializeSubtags(e, [ 'input', 'select', 'textarea' ]) + } + } + + // standard query string style serialization + function serializeQueryString() { + return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments)) + } + + // { 'name': 'value', ... } style serialization + function serializeHash() { + var hash = {} + eachFormElement.apply(function (name, value) { + if (name in hash) { + hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]]) + hash[name].push(value) + } else hash[name] = value + }, arguments) + return hash + } + + // [ { name: 'name', value: 'value' }, ... ] style serialization + reqwest.serializeArray = function () { + var arr = [] + eachFormElement.apply(function (name, value) { + arr.push({name: name, value: value}) + }, arguments) + return arr + } + + reqwest.serialize = function () { + if (arguments.length === 0) return '' + var opt, fn + , args = Array.prototype.slice.call(arguments, 0) + + opt = args.pop() + opt && opt.nodeType && args.push(opt) && (opt = null) + opt && (opt = opt.type) + + if (opt == 'map') fn = serializeHash + else if (opt == 'array') fn = reqwest.serializeArray + else fn = serializeQueryString + + return fn.apply(null, args) + } + + reqwest.toQueryString = function (o) { + var qs = '', i + , enc = encodeURIComponent + , push = function (k, v) { + qs += enc(k) + '=' + enc(v) + '&' + } + + if (isArray(o)) { + for (i = 0; o && i < o.length; i++) push(o[i].name, o[i].value) + } else { + for (var k in o) { + if (!Object.hasOwnProperty.call(o, k)) continue; + var v = o[k] + if (isArray(v)) { + for (i = 0; i < v.length; i++) push(k, v[i]) + } else push(k, o[k]) + } + } + + // spaces should be + according to spec + return qs.replace(/&$/, '').replace(/%20/g, '+') + } + + reqwest.getcallbackPrefix = function (reqId) { + return callbackPrefix + } + + // jQuery and Zepto compatibility, differences can be remapped here so you can call + // .ajax.compat(options, callback) + reqwest.compat = function (o, fn) { + if (o) { + o.type && (o.method = o.type) && delete o.type + o.dataType && (o.type = o.dataType) + o.jsonpCallback && (o.jsonpCallbackName = o.jsonpCallback) && delete o.jsonpCallback + o.jsonp && (o.jsonpCallback = o.jsonp) + } + return new Reqwest(o, fn) + } + + return reqwest }); + - $.id = function (id) { - return $([document.getElementById(id)]); - }; + provide("reqwest", module.exports); - function indexOf(ar, val) { - for (var i = 0; i < ar.length; i++) { - if (ar[i] === val) { - return i; - } - } - return -1; - } - - function uniq(ar) { - var a = [], i, j; - label: - for (i = 0; i < ar.length; i++) { - for (j = 0; j < a.length; j++) { - if (a[j] == ar[i]) { - continue label; - } - } - a[a.length] = ar[i]; - } - return a; - } - - $.ender({ - parents: function (selector, closest) { - var collection = $(selector), j, k, p, r = []; - for (j = 0, k = this.length; j < k; j++) { - p = this[j]; - while (p = p.parentNode) { - if (indexOf(collection, p) !== -1) { - r.push(p); - if (closest) break; + !function ($) { + var r = require('reqwest') + , integrate = function(method) { + return function() { + var args = Array.prototype.slice.call(arguments, 0) + , i = (this && this.length) || 0 + while (i--) args.unshift(this[i]) + return r[method].apply(null, args) } } + , s = integrate('serialize') + , sa = integrate('serializeArray') + + $.ender({ + ajax: r + , serialize: r.serialize + , serializeArray: r.serializeArray + , toQueryString: r.toQueryString + }) + + $.ender({ + serialize: s + , serializeArray: sa + }, true) + }(ender); + + +}()); + +(function () { + + var module = { exports: {} }, exports = module.exports; + + /*! + * Bean - copyright (c) Jacob Thornton 2011-2012 + * https://github.com/fat/bean + * MIT license + */ + !(function (name, context, definition) { + if (typeof module != 'undefined' && module.exports) module.exports = definition(name, context); + else if (typeof define == 'function' && typeof define.amd == 'object') define(definition); + else context[name] = definition(name, context); + }('bean', this, function (name, context) { + var win = window + , old = context[name] + , namespaceRegex = /[^\.]*(?=\..*)\.|.*/ + , nameRegex = /\..*/ + , addEvent = 'addEventListener' + , removeEvent = 'removeEventListener' + , doc = document || {} + , root = doc.documentElement || {} + , W3C_MODEL = root[addEvent] + , eventSupport = W3C_MODEL ? addEvent : 'attachEvent' + , ONE = {} // singleton for quick matching making add() do one() + + , slice = Array.prototype.slice + , str2arr = function (s, d) { return s.split(d || ' ') } + , isString = function (o) { return typeof o == 'string' } + , isFunction = function (o) { return typeof o == 'function' } + + // events that we consider to be 'native', anything not in this list will + // be treated as a custom event + , standardNativeEvents = + 'click dblclick mouseup mousedown contextmenu ' + // mouse buttons + 'mousewheel mousemultiwheel DOMMouseScroll ' + // mouse wheel + 'mouseover mouseout mousemove selectstart selectend ' + // mouse movement + 'keydown keypress keyup ' + // keyboard + 'orientationchange ' + // mobile + 'focus blur change reset select submit ' + // form elements + 'load unload beforeunload resize move DOMContentLoaded ' + // window + 'readystatechange message ' + // window + 'error abort scroll ' // misc + // element.fireEvent('onXYZ'... is not forgiving if we try to fire an event + // that doesn't actually exist, so make sure we only do these on newer browsers + , w3cNativeEvents = + 'show ' + // mouse buttons + 'input invalid ' + // form elements + 'touchstart touchmove touchend touchcancel ' + // touch + 'gesturestart gesturechange gestureend ' + // gesture + 'textinput' + // TextEvent + 'readystatechange pageshow pagehide popstate ' + // window + 'hashchange offline online ' + // window + 'afterprint beforeprint ' + // printing + 'dragstart dragenter dragover dragleave drag drop dragend ' + // dnd + 'loadstart progress suspend emptied stalled loadmetadata ' + // media + 'loadeddata canplay canplaythrough playing waiting seeking ' + // media + 'seeked ended durationchange timeupdate play pause ratechange ' + // media + 'volumechange cuechange ' + // media + 'checking noupdate downloading cached updateready obsolete ' // appcache + + // convert to a hash for quick lookups + , nativeEvents = (function (hash, events, i) { + for (i = 0; i < events.length; i++) events[i] && (hash[events[i]] = 1) + return hash + }({}, str2arr(standardNativeEvents + (W3C_MODEL ? w3cNativeEvents : '')))) + + // custom events are events that we *fake*, they are not provided natively but + // we can use native events to generate them + , customEvents = (function () { + var isAncestor = 'compareDocumentPosition' in root + ? function (element, container) { + return container.compareDocumentPosition && (container.compareDocumentPosition(element) & 16) === 16 + } + : 'contains' in root + ? function (element, container) { + container = container.nodeType === 9 || container === window ? root : container + return container !== element && container.contains(element) + } + : function (element, container) { + while (element = element.parentNode) if (element === container) return 1 + return 0 + } + , check = function (event) { + var related = event.relatedTarget + return !related + ? related == null + : (related !== this && related.prefix !== 'xul' && !/document/.test(this.toString()) + && !isAncestor(related, this)) + } + + return { + mouseenter: { base: 'mouseover', condition: check } + , mouseleave: { base: 'mouseout', condition: check } + , mousewheel: { base: /Firefox/.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel' } + } + }()) + + // we provide a consistent Event object across browsers by taking the actual DOM + // event object and generating a new one from its properties. + , Event = (function () { + // a whitelist of properties (for different event types) tells us what to check for and copy + var commonProps = str2arr('altKey attrChange attrName bubbles cancelable ctrlKey currentTarget ' + + 'detail eventPhase getModifierState isTrusted metaKey relatedNode relatedTarget shiftKey ' + + 'srcElement target timeStamp type view which propertyName') + , mouseProps = commonProps.concat(str2arr('button buttons clientX clientY dataTransfer ' + + 'fromElement offsetX offsetY pageX pageY screenX screenY toElement')) + , mouseWheelProps = mouseProps.concat(str2arr('wheelDelta wheelDeltaX wheelDeltaY wheelDeltaZ ' + + 'axis')) // 'axis' is FF specific + , keyProps = commonProps.concat(str2arr('char charCode key keyCode keyIdentifier ' + + 'keyLocation location')) + , textProps = commonProps.concat(str2arr('data')) + , touchProps = commonProps.concat(str2arr('touches targetTouches changedTouches scale rotation')) + , messageProps = commonProps.concat(str2arr('data origin source')) + , stateProps = commonProps.concat(str2arr('state')) + , overOutRegex = /over|out/ + // some event types need special handling and some need special properties, do that all here + , typeFixers = [ + { // key events + reg: /key/i + , fix: function (event, newEvent) { + newEvent.keyCode = event.keyCode || event.which + return keyProps + } + } + , { // mouse events + reg: /click|mouse(?!(.*wheel|scroll))|menu|drag|drop/i + , fix: function (event, newEvent, type) { + newEvent.rightClick = event.which === 3 || event.button === 2 + newEvent.pos = { x: 0, y: 0 } + if (event.pageX || event.pageY) { + newEvent.clientX = event.pageX + newEvent.clientY = event.pageY + } else if (event.clientX || event.clientY) { + newEvent.clientX = event.clientX + doc.body.scrollLeft + root.scrollLeft + newEvent.clientY = event.clientY + doc.body.scrollTop + root.scrollTop + } + if (overOutRegex.test(type)) { + newEvent.relatedTarget = event.relatedTarget + || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'] + } + return mouseProps + } + } + , { // mouse wheel events + reg: /mouse.*(wheel|scroll)/i + , fix: function () { return mouseWheelProps } + } + , { // TextEvent + reg: /^text/i + , fix: function () { return textProps } + } + , { // touch and gesture events + reg: /^touch|^gesture/i + , fix: function () { return touchProps } + } + , { // message events + reg: /^message$/i + , fix: function () { return messageProps } + } + , { // popstate events + reg: /^popstate$/i + , fix: function () { return stateProps } + } + , { // everything else + reg: /.*/ + , fix: function () { return commonProps } + } + ] + , typeFixerMap = {} // used to map event types to fixer functions (above), a basic cache mechanism + + , Event = function (event, element, isNative) { + if (!arguments.length) return + event = event || ((element.ownerDocument || element.document || element).parentWindow || win).event + this.originalEvent = event + this.isNative = isNative + this.isBean = true + + if (!event) return + + var type = event.type + , target = event.target || event.srcElement + , i, l, p, props, fixer + + this.target = target && target.nodeType === 3 ? target.parentNode : target + + if (isNative) { // we only need basic augmentation on custom events, the rest expensive & pointless + fixer = typeFixerMap[type] + if (!fixer) { // haven't encountered this event type before, map a fixer function for it + for (i = 0, l = typeFixers.length; i < l; i++) { + if (typeFixers[i].reg.test(type)) { // guaranteed to match at least one, last is .* + typeFixerMap[type] = fixer = typeFixers[i].fix + break + } + } + } + + props = fixer(event, this, type) + for (i = props.length; i--;) { + if (!((p = props[i]) in this) && p in event) this[p] = event[p] + } + } + } + + // preventDefault() and stopPropagation() are a consistent interface to those functions + // on the DOM, stop() is an alias for both of them together + Event.prototype.preventDefault = function () { + if (this.originalEvent.preventDefault) this.originalEvent.preventDefault() + else this.originalEvent.returnValue = false + } + Event.prototype.stopPropagation = function () { + if (this.originalEvent.stopPropagation) this.originalEvent.stopPropagation() + else this.originalEvent.cancelBubble = true + } + Event.prototype.stop = function () { + this.preventDefault() + this.stopPropagation() + this.stopped = true + } + // stopImmediatePropagation() has to be handled internally because we manage the event list for + // each element + // note that originalElement may be a Bean#Event object in some situations + Event.prototype.stopImmediatePropagation = function () { + if (this.originalEvent.stopImmediatePropagation) this.originalEvent.stopImmediatePropagation() + this.isImmediatePropagationStopped = function () { return true } + } + Event.prototype.isImmediatePropagationStopped = function () { + return this.originalEvent.isImmediatePropagationStopped && this.originalEvent.isImmediatePropagationStopped() + } + Event.prototype.clone = function (currentTarget) { + //TODO: this is ripe for optimisation, new events are *expensive* + // improving this will speed up delegated events + var ne = new Event(this, this.element, this.isNative) + ne.currentTarget = currentTarget + return ne + } + + return Event + }()) + + // if we're in old IE we can't do onpropertychange on doc or win so we use doc.documentElement for both + , targetElement = function (element, isNative) { + return !W3C_MODEL && !isNative && (element === doc || element === win) ? root : element + } + + /** + * Bean maintains an internal registry for event listeners. We don't touch elements, objects + * or functions to identify them, instead we store everything in the registry. + * Each event listener has a RegEntry object, we have one 'registry' for the whole instance. + */ + , RegEntry = (function () { + // each handler is wrapped so we can handle delegation and custom events + var wrappedHandler = function (element, fn, condition, args) { + var call = function (event, eargs) { + return fn.apply(element, args ? slice.call(eargs, event ? 0 : 1).concat(args) : eargs) + } + , findTarget = function (event, eventElement) { + return fn.__beanDel ? fn.__beanDel.ft(event.target, element) : eventElement + } + , handler = condition + ? function (event) { + var target = findTarget(event, this) // deleated event + if (condition.apply(target, arguments)) { + if (event) event.currentTarget = target + return call(event, arguments) + } + } + : function (event) { + if (fn.__beanDel) event = event.clone(findTarget(event)) // delegated event, fix the fix + return call(event, arguments) + } + handler.__beanDel = fn.__beanDel + return handler + } + + , RegEntry = function (element, type, handler, original, namespaces, args, root) { + var customType = customEvents[type] + , isNative + + if (type == 'unload') { + // self clean-up + handler = once(removeListener, element, type, handler, original) + } + + if (customType) { + if (customType.condition) { + handler = wrappedHandler(element, handler, customType.condition, args) + } + type = customType.base || type + } + + this.isNative = isNative = nativeEvents[type] && !!element[eventSupport] + this.customType = !W3C_MODEL && !isNative && type + this.element = element + this.type = type + this.original = original + this.namespaces = namespaces + this.eventType = W3C_MODEL || isNative ? type : 'propertychange' + this.target = targetElement(element, isNative) + this[eventSupport] = !!this.target[eventSupport] + this.root = root + this.handler = wrappedHandler(element, handler, null, args) + } + + // given a list of namespaces, is our entry in any of them? + RegEntry.prototype.inNamespaces = function (checkNamespaces) { + var i, j, c = 0 + if (!checkNamespaces) return true + if (!this.namespaces) return false + for (i = checkNamespaces.length; i--;) { + for (j = this.namespaces.length; j--;) { + if (checkNamespaces[i] == this.namespaces[j]) c++ + } + } + return checkNamespaces.length === c + } + + // match by element, original fn (opt), handler fn (opt) + RegEntry.prototype.matches = function (checkElement, checkOriginal, checkHandler) { + return this.element === checkElement && + (!checkOriginal || this.original === checkOriginal) && + (!checkHandler || this.handler === checkHandler) + } + + return RegEntry + }()) + + , registry = (function () { + // our map stores arrays by event type, just because it's better than storing + // everything in a single array. + // uses '$' as a prefix for the keys for safety and 'r' as a special prefix for + // rootListeners so we can look them up fast + var map = {} + + // generic functional search of our registry for matching listeners, + // `fn` returns false to break out of the loop + , forAll = function (element, type, original, handler, root, fn) { + var pfx = root ? 'r' : '$' + if (!type || type == '*') { + // search the whole registry + for (var t in map) { + if (t.charAt(0) == pfx) { + forAll(element, t.substr(1), original, handler, root, fn) + } + } + } else { + var i = 0, l, list = map[pfx + type], all = element == '*' + if (!list) return + for (l = list.length; i < l; i++) { + if ((all || list[i].matches(element, original, handler)) && !fn(list[i], list, i, type)) return + } + } + } + + , has = function (element, type, original, root) { + // we're not using forAll here simply because it's a bit slower and this + // needs to be fast + var i, list = map[(root ? 'r' : '$') + type] + if (list) { + for (i = list.length; i--;) { + if (!list[i].root && list[i].matches(element, original, null)) return true + } + } + return false + } + + , get = function (element, type, original, root) { + var entries = [] + forAll(element, type, original, null, root, function (entry) { + return entries.push(entry) + }) + return entries + } + + , put = function (entry) { + var has = !entry.root && !this.has(entry.element, entry.type, null, false) + , key = (entry.root ? 'r' : '$') + entry.type + ;(map[key] || (map[key] = [])).push(entry) + return has + } + + , del = function (entry) { + forAll(entry.element, entry.type, null, entry.handler, entry.root, function (entry, list, i) { + list.splice(i, 1) + entry.removed = true + if (list.length === 0) delete map[(entry.root ? 'r' : '$') + entry.type] + return false + }) + } + + // dump all entries, used for onunload + , entries = function () { + var t, entries = [] + for (t in map) { + if (t.charAt(0) == '$') entries = entries.concat(map[t]) + } + return entries + } + + return { has: has, get: get, put: put, del: del, entries: entries } + }()) + + // we need a selector engine for delegated events, use querySelectorAll if it exists + // but for older browsers we need Qwery, Sizzle or similar + , selectorEngine + , setSelectorEngine = function (e) { + if (!arguments.length) { + selectorEngine = doc.querySelectorAll + ? function (s, r) { + return r.querySelectorAll(s) + } + : function () { + throw new Error('Bean: No selector engine installed') // eeek + } + } else { + selectorEngine = e + } + } + + // we attach this listener to each DOM event that we need to listen to, only once + // per event type per DOM element + , rootListener = function (event, type) { + if (!W3C_MODEL && type && event && event.propertyName != '_on' + type) return + + var listeners = registry.get(this, type || event.type, null, false) + , l = listeners.length + , i = 0 + + event = new Event(event, this, true) + if (type) event.type = type + + // iterate through all handlers registered for this type, calling them unless they have + // been removed by a previous handler or stopImmediatePropagation() has been called + for (; i < l && !event.isImmediatePropagationStopped(); i++) { + if (!listeners[i].removed) listeners[i].handler.call(this, event) + } + } + + // add and remove listeners to DOM elements + , listener = W3C_MODEL + ? function (element, type, add) { + // new browsers + element[add ? addEvent : removeEvent](type, rootListener, false) + } + : function (element, type, add, custom) { + // IE8 and below, use attachEvent/detachEvent and we have to piggy-back propertychange events + // to simulate event bubbling etc. + var entry + if (add) { + registry.put(entry = new RegEntry( + element + , custom || type + , function (event) { // handler + rootListener.call(element, event, custom) + } + , rootListener + , null + , null + , true // is root + )) + if (custom && element['_on' + custom] == null) element['_on' + custom] = 0 + entry.target.attachEvent('on' + entry.eventType, entry.handler) + } else { + entry = registry.get(element, custom || type, rootListener, true)[0] + if (entry) { + entry.target.detachEvent('on' + entry.eventType, entry.handler) + registry.del(entry) + } + } + } + + , once = function (rm, element, type, fn, originalFn) { + // wrap the handler in a handler that does a remove as well + return function () { + fn.apply(this, arguments) + rm(element, type, originalFn) + } + } + + , removeListener = function (element, orgType, handler, namespaces) { + var type = orgType && orgType.replace(nameRegex, '') + , handlers = registry.get(element, type, null, false) + , removed = {} + , i, l + + for (i = 0, l = handlers.length; i < l; i++) { + if ((!handler || handlers[i].original === handler) && handlers[i].inNamespaces(namespaces)) { + // TODO: this is problematic, we have a registry.get() and registry.del() that + // both do registry searches so we waste cycles doing this. Needs to be rolled into + // a single registry.forAll(fn) that removes while finding, but the catch is that + // we'll be splicing the arrays that we're iterating over. Needs extra tests to + // make sure we don't screw it up. @rvagg + registry.del(handlers[i]) + if (!removed[handlers[i].eventType] && handlers[i][eventSupport]) + removed[handlers[i].eventType] = { t: handlers[i].eventType, c: handlers[i].type } + } + } + // check each type/element for removed listeners and remove the rootListener where it's no longer needed + for (i in removed) { + if (!registry.has(element, removed[i].t, null, false)) { + // last listener of this type, remove the rootListener + listener(element, removed[i].t, false, removed[i].c) + } + } + } + + // set up a delegate helper using the given selector, wrap the handler function + , delegate = function (selector, fn) { + //TODO: findTarget (therefore $) is called twice, once for match and once for + // setting e.currentTarget, fix this so it's only needed once + var findTarget = function (target, root) { + var i, array = isString(selector) ? selectorEngine(selector, root) : selector + for (; target && target !== root; target = target.parentNode) { + for (i = array.length; i--;) { + if (array[i] === target) return target + } + } + } + , handler = function (e) { + var match = findTarget(e.target, this) + if (match) fn.apply(match, arguments) + } + + // __beanDel isn't pleasant but it's a private function, not exposed outside of Bean + handler.__beanDel = { + ft : findTarget // attach it here for customEvents to use too + , selector : selector + } + return handler + } + + , fireListener = W3C_MODEL ? function (isNative, type, element) { + // modern browsers, do a proper dispatchEvent() + var evt = doc.createEvent(isNative ? 'HTMLEvents' : 'UIEvents') + evt[isNative ? 'initEvent' : 'initUIEvent'](type, true, true, win, 1) + element.dispatchEvent(evt) + } : function (isNative, type, element) { + // old browser use onpropertychange, just increment a custom property to trigger the event + element = targetElement(element, isNative) + isNative ? element.fireEvent('on' + type, doc.createEventObject()) : element['_on' + type]++ + } + + /** + * Public API: off(), on(), add(), (remove()), one(), fire(), clone() + */ + + /** + * off(element[, eventType(s)[, handler ]]) + */ + , off = function (element, typeSpec, fn) { + var isTypeStr = isString(typeSpec) + , k, type, namespaces, i + + if (isTypeStr && typeSpec.indexOf(' ') > 0) { + // off(el, 't1 t2 t3', fn) or off(el, 't1 t2 t3') + typeSpec = str2arr(typeSpec) + for (i = typeSpec.length; i--;) + off(element, typeSpec[i], fn) + return element + } + + type = isTypeStr && typeSpec.replace(nameRegex, '') + if (type && customEvents[type]) type = customEvents[type].base + + if (!typeSpec || isTypeStr) { + // off(el) or off(el, t1.ns) or off(el, .ns) or off(el, .ns1.ns2.ns3) + if (namespaces = isTypeStr && typeSpec.replace(namespaceRegex, '')) namespaces = str2arr(namespaces, '.') + removeListener(element, type, fn, namespaces) + } else if (isFunction(typeSpec)) { + // off(el, fn) + removeListener(element, null, typeSpec) + } else { + // off(el, { t1: fn1, t2, fn2 }) + for (k in typeSpec) { + if (typeSpec.hasOwnProperty(k)) off(element, k, typeSpec[k]) + } + } + + return element + } + + /** + * on(element, eventType(s)[, selector], handler[, args ]) + */ + , on = function(element, events, selector, fn) { + var originalFn, type, types, i, args, entry, first + + //TODO: the undefined check means you can't pass an 'args' argument, fix this perhaps? + if (selector === undefined && typeof events == 'object') { + //TODO: this can't handle delegated events + for (type in events) { + if (events.hasOwnProperty(type)) { + on.call(this, element, type, events[type]) + } + } + return + } + + if (!isFunction(selector)) { + // delegated event + originalFn = fn + args = slice.call(arguments, 4) + fn = delegate(selector, originalFn, selectorEngine) + } else { + args = slice.call(arguments, 3) + fn = originalFn = selector + } + + types = str2arr(events) + + // special case for one(), wrap in a self-removing handler + if (this === ONE) { + fn = once(off, element, events, fn, originalFn) + } + + for (i = types.length; i--;) { + // add new handler to the registry and check if it's the first for this element/type + first = registry.put(entry = new RegEntry( + element + , types[i].replace(nameRegex, '') // event type + , fn + , originalFn + , str2arr(types[i].replace(namespaceRegex, ''), '.') // namespaces + , args + , false // not root + )) + if (entry[eventSupport] && first) { + // first event of this type on this element, add root listener + listener(element, entry.eventType, true, entry.customType) + } + } + + return element + } + + /** + * add(element[, selector], eventType(s), handler[, args ]) + * + * Deprecated: kept (for now) for backward-compatibility + */ + , add = function (element, events, fn, delfn) { + return on.apply( + null + , !isString(fn) + ? slice.call(arguments) + : [ element, fn, events, delfn ].concat(arguments.length > 3 ? slice.call(arguments, 5) : []) + ) + } + + /** + * one(element, eventType(s)[, selector], handler[, args ]) + */ + , one = function () { + return on.apply(ONE, arguments) + } + + /** + * fire(element, eventType(s)[, args ]) + * + * The optional 'args' argument must be an array, if no 'args' argument is provided + * then we can use the browser's DOM event system, otherwise we trigger handlers manually + */ + , fire = function (element, type, args) { + var types = str2arr(type) + , i, j, l, names, handlers + + for (i = types.length; i--;) { + type = types[i].replace(nameRegex, '') + if (names = types[i].replace(namespaceRegex, '')) names = str2arr(names, '.') + if (!names && !args && element[eventSupport]) { + fireListener(nativeEvents[type], type, element) + } else { + // non-native event, either because of a namespace, arguments or a non DOM element + // iterate over all listeners and manually 'fire' + handlers = registry.get(element, type, null, false) + args = [false].concat(args) + for (j = 0, l = handlers.length; j < l; j++) { + if (handlers[j].inNamespaces(names)) { + handlers[j].handler.apply(element, args) + } + } + } + } + return element + } + + /** + * clone(dstElement, srcElement[, eventType ]) + * + * TODO: perhaps for consistency we should allow the same flexibility in type specifiers? + */ + , clone = function (element, from, type) { + var handlers = registry.get(from, type, null, false) + , l = handlers.length + , i = 0 + , args, beanDel + + for (; i < l; i++) { + if (handlers[i].original) { + args = [ element, handlers[i].type ] + if (beanDel = handlers[i].handler.__beanDel) args.push(beanDel.selector) + args.push(handlers[i].original) + on.apply(null, args) + } + } + return element + } + + , bean = { + on : on + , add : add + , one : one + , off : off + , remove : off + , clone : clone + , fire : fire + , setSelectorEngine : setSelectorEngine + , noConflict : function () { + context[name] = old + return this + } + } + + // for IE, clean up on unload to avoid leaks + if (win.attachEvent) { + var cleanup = function () { + var i, entries = registry.entries() + for (i in entries) { + if (entries[i].type && entries[i].type !== 'unload') off(entries[i].element, entries[i].type) + } + win.detachEvent('onunload', cleanup) + win.CollectGarbage && win.CollectGarbage() } - return $(uniq(r)); - }, - - closest: function (selector) { - return this.parents(selector, true); - }, - - first: function () { - return $(this[0]); - }, - - last: function () { - return $(this[this.length - 1]); - }, - - next: function () { - return $(b(this).next()); - }, - - previous: function () { - return $(b(this).previous()); - }, - - appendTo: function (t) { - return b(this.selector).appendTo(t, this); - }, - - prependTo: function (t) { - return b(this.selector).prependTo(t, this); - }, - - insertAfter: function (t) { - return b(this.selector).insertAfter(t, this); - }, - - insertBefore: function (t) { - return b(this.selector).insertBefore(t, this); - }, - - siblings: function () { - var i, l, p, r = []; - for (i = 0, l = this.length; i < l; i++) { - p = this[i]; - while (p = p.previousSibling) { - p.nodeType == 1 && r.push(p); - } - p = this[i]; - while (p = p.nextSibling) { - p.nodeType == 1 && r.push(p); - } - } - return $(r); - }, - - children: function () { - var el, r = []; - for (i = 0, l = this.length; i < l; i++) { - if (!(el = b.firstChild(this[i]))) { - continue; - } - r.push(el); - while (el = el.nextSibling) { - el.nodeType == 1 && r.push(el); - } - } - return $(uniq(r)); - }, - - height: function (v) { - return v ? this.css('height', v) : parseInt(this.css('height'), 10); - }, - - width: function (v) { - return v ? this.css('width', v) : parseInt(this.css('width'), 10); - } - }, true); - -}(ender || $); - -!function () { var exports = {}, module = { exports: exports }; !function (doc) { - var loaded = 0, fns = [], ol, f = false, - testEl = doc.createElement('a'), - domContentLoaded = 'DOMContentLoaded', - addEventListener = 'addEventListener', - onreadystatechange = 'onreadystatechange'; - - /^loade|c/.test(doc.readyState) && (loaded = 1); - - function flush() { - loaded = 1; - for (var i = 0, l = fns.length; i < l; i++) { - fns[i](); - } - } - doc[addEventListener] && doc[addEventListener](domContentLoaded, function fn() { - doc.removeEventListener(domContentLoaded, fn, f); - flush(); - }, f); - - - testEl.doScroll && doc.attachEvent(onreadystatechange, (ol = function ol() { - if (/^c/.test(doc.readyState)) { - doc.detachEvent(onreadystatechange, ol); - flush(); + win.attachEvent('onunload', cleanup) } + + // initialize selector engine to internal default (qSA or throw Error) + setSelectorEngine() + + return bean })); + - var domReady = testEl.doScroll ? - function (fn) { - self != top ? - !loaded ? - fns.push(fn) : - fn() : - !function () { + provide("bean", module.exports); + + !function ($) { + var b = require('bean') + + , integrate = function (method, type, method2) { + var _args = type ? [type] : [] + return function () { + for (var i = 0, l = this.length; i < l; i++) { + if (!arguments.length && method == 'on' && type) method = 'fire' + b[method].apply(this, [this[i]].concat(_args, Array.prototype.slice.call(arguments, 0))) + } + return this + } + } + + , add = integrate('add') + , on = integrate('on') + , one = integrate('one') + , off = integrate('off') + , fire = integrate('fire') + , clone = integrate('clone') + + , hover = function (enter, leave, i) { // i for internal + for (i = this.length; i--;) { + b.on.call(this, this[i], 'mouseenter', enter) + b.on.call(this, this[i], 'mouseleave', leave) + } + return this + } + + , methods = { + on : on + , addListener : on + , bind : on + , listen : on + , delegate : add // jQuery compat, same arg order as add() + + , one : one + + , off : off + , unbind : off + , unlisten : off + , removeListener : off + , undelegate : off + + , emit : fire + , trigger : fire + + , cloneEvents : clone + + , hover : hover + } + + , shortcuts = + ('blur change click dblclick error focus focusin focusout keydown keypress ' + + 'keyup load mousedown mouseenter mouseleave mouseout mouseover mouseup ' + + 'mousemove resize scroll select submit unload').split(' ') + + for (var i = shortcuts.length; i--;) { + methods[shortcuts[i]] = integrate('on', shortcuts[i]) + } + + b.setSelectorEngine($) + + $.ender(methods, true) + }(ender); + +}()); + +(function () { + + var module = { exports: {} }, exports = module.exports; + + /*! + * Bonzo: DOM Utility (c) Dustin Diaz 2012 + * https://github.com/ded/bonzo + * License MIT + */ + (function (name, context, definition) { + if (typeof module != 'undefined' && module.exports) module.exports = definition() + else if (typeof context['define'] == 'function' && context['define']['amd']) define(definition) + else context[name] = definition() + })('bonzo', this, function() { + var win = window + , doc = win.document + , html = doc.documentElement + , parentNode = 'parentNode' + , specialAttributes = /^(checked|value|selected|disabled)$/i + , specialTags = /^(select|fieldset|table|tbody|tfoot|td|tr|colgroup)$/i // tags that we have trouble inserting *into* + , simpleScriptTagRe = /\s*