From 705357519b7345422a003d8970d1f396579d91b2 Mon Sep 17 00:00:00 2001 From: Samrat Man Singh Date: Sat, 7 Jul 2012 08:28:26 +0545 Subject: Add syte-pelican, a theme based on Syte --- syte-pelican/static/js/components/base.js | 32 + syte-pelican/static/js/components/blog-posts.js | 143 +++ syte-pelican/static/js/components/dribbble.js | 53 + syte-pelican/static/js/components/github.js | 46 + syte-pelican/static/js/components/instagram.js | 66 + syte-pelican/static/js/components/links.js | 67 + syte-pelican/static/js/components/mobile.js | 15 + syte-pelican/static/js/components/twitter.js | 82 ++ syte-pelican/static/js/libs/bootstrap-modal.js | 222 ++++ syte-pelican/static/js/libs/handlebars.js | 1550 +++++++++++++++++++++++ syte-pelican/static/js/libs/jquery.url.js | 162 +++ syte-pelican/static/js/libs/json.js | 42 + syte-pelican/static/js/libs/moment.min.js | 6 + syte-pelican/static/js/libs/prettify.js | 28 + syte-pelican/static/js/libs/require.js | 33 + syte-pelican/static/js/libs/spin.min.js | 2 + syte-pelican/static/js/libs/text.js | 11 + syte-pelican/static/js/min/scripts.min.js | 8 + 18 files changed, 2568 insertions(+) create mode 100644 syte-pelican/static/js/components/base.js create mode 100644 syte-pelican/static/js/components/blog-posts.js create mode 100644 syte-pelican/static/js/components/dribbble.js create mode 100644 syte-pelican/static/js/components/github.js create mode 100644 syte-pelican/static/js/components/instagram.js create mode 100644 syte-pelican/static/js/components/links.js create mode 100644 syte-pelican/static/js/components/mobile.js create mode 100644 syte-pelican/static/js/components/twitter.js create mode 100755 syte-pelican/static/js/libs/bootstrap-modal.js create mode 100644 syte-pelican/static/js/libs/handlebars.js create mode 100755 syte-pelican/static/js/libs/jquery.url.js create mode 100644 syte-pelican/static/js/libs/json.js create mode 100644 syte-pelican/static/js/libs/moment.min.js create mode 100644 syte-pelican/static/js/libs/prettify.js create mode 100644 syte-pelican/static/js/libs/require.js create mode 100644 syte-pelican/static/js/libs/spin.min.js create mode 100644 syte-pelican/static/js/libs/text.js create mode 100644 syte-pelican/static/js/min/scripts.min.js (limited to 'syte-pelican/static/js') diff --git a/syte-pelican/static/js/components/base.js b/syte-pelican/static/js/components/base.js new file mode 100644 index 0000000..0d60276 --- /dev/null +++ b/syte-pelican/static/js/components/base.js @@ -0,0 +1,32 @@ +//Global configs and functions shared between js + +function numberWithCommas(x) { + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); +} + +require.config({ + baseUrl: "/static/", + paths: { + "text": "js/libs/text", + "json": "js/libs/json" + }, + waitSeconds: 15 +}); + +var spin_opts = { + lines: 9, + length: 5, + width: 2, + radius: 4, + rotate: 9, + color: '#4c4c4c', + speed: 1.5, + trail: 40, + shadow: false, + hwaccel: false, + className: 'spinner', + zIndex: 2e9 +}; + + + diff --git a/syte-pelican/static/js/components/blog-posts.js b/syte-pelican/static/js/components/blog-posts.js new file mode 100644 index 0000000..27f8ab5 --- /dev/null +++ b/syte-pelican/static/js/components/blog-posts.js @@ -0,0 +1,143 @@ + +function fetchBlogPosts(post, tag) { + var blog_fetch_url = '/blog.json'; + + if (post) + blog_fetch_url = '/post/' + post; + else if (tag) + blog_fetch_url = '/tags/' + tag; + + $.getJSON(blog_fetch_url, function(blog_posts) { + require(["text!templates/blog-post-text.html", + "text!templates/blog-post-photo.html", + "text!templates/blog-post-link.html", + "text!templates/blog-post-video.html", + "text!templates/blog-post-audio.html", + "text!templates/blog-post-quote.html"], + + function(text_post_template, photo_post_template, + link_post_template, video_post_template, audio_post_template, + quote_post_template) { + + var text_template = Handlebars.compile(text_post_template); + var photo_template = Handlebars.compile(photo_post_template); + var link_template = Handlebars.compile(link_post_template); + var video_template = Handlebars.compile(video_post_template); + var audio_template = Handlebars.compile(audio_post_template); + var quote_template = Handlebars.compile(quote_post_template); + + $('.loading').remove(); + $.each(blog_posts.response.posts, function(i, p) { + p.formated_date = moment(p.date).format('MMMM DD, YYYY') + + if (p.type == 'text') + $('#blog-posts').append(text_template(p)); + else if (p.type == 'photo') + $('#blog-posts').append(photo_template(p)); + else if (p.type == 'link') + $('#blog-posts').append(link_template(p)); + else if (p.type == 'video') + $('#blog-posts').append(video_template(p)); + else if (p.type == 'audio') + $('#blog-posts').append(audio_template(p)); + else if (p.type == 'quote') + $('#blog-posts').append(quote_template(p)); + + }); + + setupLinks(); + adjustBlogHeaders(); + prettyPrint(); + setTimeout(setupBlogHeaderScroll, 1000); + adjustSelection('home-link'); + }); + }); +} + +function adjustBlogHeaders() { + if(isMobileView) + return; + + $('.blog-section article hgroup').each(function(i, e) { + $(e).find('h3 a').css({ + 'margin-top': '-' + ($(e).height() + 100) + 'px' + }).addClass('adjusted'); + }); +} + +function setupBlogHeaderScroll() { + + if(isMobileView) + return; + + var previousTarget, + activeTarget, + $window = $(window), + offsets = [], + targets = [], + $posts = $('.blog-section article hgroup h3 a').each(function() { + if (this.hash) { + targets.push(this.hash); + offsets.push($(this.hash).offset().top); + } + }); + + function processScroll(e) { + var scrollTop = $window.scrollTop(), + i = offsets.length; + + for (i; i--;) { + if (activeTarget != targets[i] && scrollTop > offsets[i] && (!offsets[i + 1] || scrollTop < offsets[i + 1])) { + + var hgroup = $(activeTarget).find("hgroup"); + var margintop = ''; + if (hgroup.length) { + margintop = '-' + ($(hgroup[0]).height() + 100) + 'px'; + } + + //set current target to be absolute + $("h3 a[href=" + activeTarget + "]").removeClass("active").css({ + position: "absolute", + top: "auto", + 'margin-top': margintop + }); + + //set new target to be fixed + activeTarget = targets[i]; + $("h3 a[href=" + activeTarget + "]").attr('style', '').addClass("active"); + } + + if (activeTarget && activeTarget != targets[i] && scrollTop + 50 >= offsets[i] && (!offsets[i + 1] || scrollTop + 50 <= offsets[i + 1])) { + + // if it's close to the new target scroll the current target up + $("h3 a[href=" + activeTarget + "]") + .removeClass("active") + .css({ + position: "absolute", + top: ($(activeTarget).outerHeight(true) + $(activeTarget).offset().top - 50) + "px", + bottom: "auto" + }); + } + + if (activeTarget == targets[i] && scrollTop > offsets[i] - 50 && (!offsets[i + 1] || scrollTop <= offsets[i + 1] - 50)) { + // if the current target is not fixed make it fixed. + if (!$("h3 a[href=" + activeTarget + "]").hasClass("active")) { + $("h3 a[href=" + activeTarget + "]").attr('style', '').addClass("active"); + } + } + } + } + + $posts.click(function(e) { + if (!this.hash) + return; + $('html, body').stop().animate({ + scrollTop: $(this.hash).offset().top + }, 500, 'linear'); + + processScroll(); + e.preventDefault(); + }); + + $window.scroll(processScroll).trigger("scroll"); +} diff --git a/syte-pelican/static/js/components/dribbble.js b/syte-pelican/static/js/components/dribbble.js new file mode 100644 index 0000000..7c2ed59 --- /dev/null +++ b/syte-pelican/static/js/components/dribbble.js @@ -0,0 +1,53 @@ + +function setupDribbble(url, el) { + var href = el.href; + + if ($('#dribbble-profile').length > 0) { + window.location = href; + return; + } + + var params = url.attr('path').split('/').filter(function(w) { + if (w.length) + return true; + return false; + }) + + if (params.length == 1) { + var username = params[0]; + + var spinner = new Spinner(spin_opts).spin(); + $('#dribbble-link').append(spinner.el); + + require(["json!/dribbble/" + username, "text!templates/dribbble-view.html"], + function(dribbble_data, dribbble_view) { + if (dribbble_data.message || dribbble_data.length == 0) { + window.location = href; + return; + } + + var template = Handlebars.compile(dribbble_view); + + var user = dribbble_data.shots[0].player; + user.following_count = numberWithCommas(user.following_count); + user.followers_count = numberWithCommas(user.followers_count); + user.likes_count = numberWithCommas(user.likes_count); + + var template_data = { + "user": user, + "shots": dribbble_data.shots + } + + $(template(template_data)).modal().on('hidden', function () { + $(this).remove(); + adjustSelection('home-link'); + }) + + spinner.stop(); + }); + + return; + } + + window.location = href; +} diff --git a/syte-pelican/static/js/components/github.js b/syte-pelican/static/js/components/github.js new file mode 100644 index 0000000..7bad5ea --- /dev/null +++ b/syte-pelican/static/js/components/github.js @@ -0,0 +1,46 @@ + +function setupGithub(url, el) { + var href = el.href; + + if ($('#github-profile').length > 0) { + window.location = href; + return; + } + + var params = url.attr('path').split('/').filter(function(w) { + if (w.length) + return true; + return false; + }) + + if (params.length == 1) { + var username = params[0]; + + var spinner = new Spinner(spin_opts).spin(); + $('#github-link').append(spinner.el); + + require(["json!/github/" + username, "text!templates/github-view.html"], + function(github_data, github_view) { + if (github_data.error || github_data.length == 0) { + window.location = href; + return; + } + + var template = Handlebars.compile(github_view); + github_data.user.following_count = numberWithCommas(github_data.user.following_count) + github_data.user.followers_count = numberWithCommas(github_data.user.followers_count) + + $(template(github_data)).modal().on('hidden', function () { + $(this).remove(); + adjustSelection('home-link'); + }) + + spinner.stop(); + + }); + + return; + } + + window.location = href; +} diff --git a/syte-pelican/static/js/components/instagram.js b/syte-pelican/static/js/components/instagram.js new file mode 100644 index 0000000..3c6dc3a --- /dev/null +++ b/syte-pelican/static/js/components/instagram.js @@ -0,0 +1,66 @@ + +function setupInstagram(el) { + var href = el.href; + + if($('#instagram-profile').length > 0) { + window.location = href; + return; + } + + var spinner = new Spinner(spin_opts).spin(); + $('#instagram-link').append(spinner.el); + + require(["json!/instagram/", + "text!templates/instagram-view.html", + "text!templates/instagram-view-more.html"], + function(instagram_data, instagram_view, instagram_view_more) { + if (instagram_data.media == 0){ + window.location = href; + return; + } + + var template = Handlebars.compile(instagram_view); + + var user_counts = instagram_data.user['counts']; + user_counts.media = numberWithCommas(user_counts.media); + user_counts.followed_by = numberWithCommas(user_counts.followed_by); + user_counts.follows = numberWithCommas(user_counts.follows); + + $.each(instagram_data.media, function(i, p) { + p.formated_date = moment.unix(parseInt(p.created_time)).fromNow(); + }); + + $(template(instagram_data)).modal().on('hidden', function () { + $(this).remove(); + adjustSelection('home-link'); + }) + + var more_template = Handlebars.compile(instagram_view_more); + + $('#load-more-pics').click(function(e) { + next = $(this).attr('data-control-next'); + + var spinner = new Spinner(spin_opts).spin(); + $('#load-more-pics').append(spinner.el); + + $.getJSON('/instagram/' + next, function(data) { + + $.each(data.media, function(i, p) { + p.formated_date = moment.unix(parseInt(p.created_time)).fromNow(); + }); + + $('.instagram .profile-shots').append(more_template(data)); + + if (data.pagination && data.pagination['next_max_id']) + $('#load-more-pics').attr('data-control-next', data.pagination['next_max_id']); + else + $('#load-more-pics').remove(); + + spinner.stop(); + }); + + }) + + spinner.stop(); + }); +} diff --git a/syte-pelican/static/js/components/links.js b/syte-pelican/static/js/components/links.js new file mode 100644 index 0000000..0671f6a --- /dev/null +++ b/syte-pelican/static/js/components/links.js @@ -0,0 +1,67 @@ + +function setupLinks() { + + $('a').click(function(e) { + e.preventDefault(); + e.stopPropagation(); + + var url = $.url(this.href.replace('/#!', '')); + + if (this.id == 'home-link' && window.location.pathname == '/') { + $('#github-profile').remove(); + $('#dribbble-profile').remove(); + $('#twitter-profile').remove(); + $('#instagram-profile').remove(); + $('.modal-backdrop').remove(); + adjustSelection('home-link'); + } + else if(this.id == 'instagram-link' && instagram_integration_enabled) { + $('#github-profile').remove(); + $('#dribbble-profile').remove(); + $('#twitter-profile').remove(); + $('.modal-backdrop').remove(); + adjustSelection('instagram-link'); + + setupInstagram(this); + } + else if (twitter_integration_enabled && (url.attr('host') == 'twitter.com' || url.attr('host') == 'www.twitter.com')) { + + $('#github-profile').remove(); + $('#dribbble-profile').remove(); + $('#instagram-profile').remove(); + $('.modal-backdrop').remove(); + adjustSelection('twitter-link'); + + setupTwitter(url, this); + } + else if (github_integration_enabled && (url.attr('host') == 'github.com' || url.attr('host') == 'www.github.com')) { + + $('#twitter-profile').remove(); + $('#dribbble-profile').remove(); + $('#instagram-profile').remove(); + $('.modal-backdrop').remove(); + adjustSelection('github-link'); + + setupGithub(url, this); + } + else if (dribbble_integration_enabled && (url.attr('host') == 'dribbble.com' || url.attr('host') == 'www.dribbble.com')) { + + $('#twitter-profile').remove(); + $('#github-profile').remove(); + $('#instagram-profile').remove(); + $('.modal-backdrop').remove(); + adjustSelection('dribbble-link'); + + setupDribbble(url, this); + } + else { + window.location = this.href; + } + }); +} + +function adjustSelection(el) { + $('.main-nav').children('li').removeClass('sel'); + $('#' + el).parent().addClass('sel'); +} + diff --git a/syte-pelican/static/js/components/mobile.js b/syte-pelican/static/js/components/mobile.js new file mode 100644 index 0000000..4b530b3 --- /dev/null +++ b/syte-pelican/static/js/components/mobile.js @@ -0,0 +1,15 @@ + +var isMobileView = false; +var mediaQuery = window.matchMedia("(max-width:600px)"); + +if (mediaQuery.matches) { + isMobileView = true; +} + +$(function() { + $('#mobile-nav-btn').click(function() { + $('.main-section').toggleClass('nav-opened'); + }); +}); + + diff --git a/syte-pelican/static/js/components/twitter.js b/syte-pelican/static/js/components/twitter.js new file mode 100644 index 0000000..4a8bb30 --- /dev/null +++ b/syte-pelican/static/js/components/twitter.js @@ -0,0 +1,82 @@ + +function setupTwitter(url, el) { + var href = el.href; + + if ($('#twitter-profile').length > 0) { + window.location = href; + return; + } + + var params = url.attr('path').split('/').filter(function(w) { + if (w.length) + return true; + return false; + }) + + if (params.length == 1) { + var username = params[0]; + + var spinner = new Spinner(spin_opts).spin(); + $('#twitter-link').append(spinner.el); + + require(["json!/twitter/" + username, "text!templates/twitter-view.html"], + function(twitter_data, twitter_view) { + if (twitter_data.error || twitter_data.length == 0) { + window.location = href; + return; + } + + var template = Handlebars.compile(twitter_view); + + var tweets = []; + $.each(twitter_data, function(i, t) { + if (i > 3) + return; + + //'ddd MMM DD HH:mm:ss ZZ YYYY' + t.formated_date = moment(t.created_at).fromNow(); + t.f_text = twitterLinkify(t.text); + tweets.push(t); + }); + + var user = twitter_data[0].user; + user.statuses_count = numberWithCommas(user.statuses_count); + user.friends_count = numberWithCommas(user.friends_count); + user.followers_count = numberWithCommas(user.followers_count); + user.f_description = twitterLinkify(user.description); + + var template_data = { + "user": user, + "tweets": tweets + } + + $(template(template_data)).modal().on('hidden', function () { + $(this).remove(); + adjustSelection('home-link'); + }) + + spinner.stop(); + }); + + return; + } + + window.location = href; +} + +function twitterLinkify(text) { + text = text.replace(/(https?:\/\/\S+)/gi, function (s) { + return '' + s + ''; + }); + + text = text.replace(/(^|) @(\w+)/gi, function (s) { + return '' + s + ''; + }); + + text = text.replace(/(^|) #(\w+)/gi, function (s) { + return '' + s + ''; + }); + + return text; +} + diff --git a/syte-pelican/static/js/libs/bootstrap-modal.js b/syte-pelican/static/js/libs/bootstrap-modal.js new file mode 100755 index 0000000..f6d94f5 --- /dev/null +++ b/syte-pelican/static/js/libs/bootstrap-modal.js @@ -0,0 +1,222 @@ +/* ========================================================= + * bootstrap-modal.js v2.0.3 + * http://twitter.github.com/bootstrap/javascript.html#modals + * ========================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* MODAL CLASS DEFINITION + * ====================== */ + + var Modal = function (content, options) { + this.options = options + this.$element = $(content) + .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) + } + + Modal.prototype = { + + constructor: Modal + + , toggle: function () { + return this[!this.isShown ? 'show' : 'hide']() + } + + , show: function () { + var that = this + , e = $.Event('show') + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + $('body').addClass('modal-open') + + this.isShown = true + + escape.call(this) + backdrop.call(this, function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(document.body) //don't move modals dom position + } + + that.$element + .show() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + //this mobile part is custom, im too lasy to extend this feature for this + if (isMobileView) + that.$element.css('top', (window.pageYOffset + 45) + 'px'); + + that.$element.addClass('in') + + transition ? + that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) : + that.$element.trigger('shown') + + }) + } + + , hide: function (e) { + e && e.preventDefault() + + var that = this + + e = $.Event('hide') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + $('body').removeClass('modal-open') + + escape.call(this) + + this.$element.removeClass('in') + + $.support.transition && this.$element.hasClass('fade') ? + hideWithTransition.call(this) : + hideModal.call(this) + } + + } + + + /* MODAL PRIVATE METHODS + * ===================== */ + + function hideWithTransition() { + var that = this + , timeout = setTimeout(function () { + that.$element.off($.support.transition.end) + hideModal.call(that) + }, 500) + + this.$element.one($.support.transition.end, function () { + clearTimeout(timeout) + hideModal.call(that) + }) + } + + function hideModal(that) { + this.$element + .hide() + .trigger('hidden') + + backdrop.call(this) + } + + function backdrop(callback) { + var that = this + , animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $('