Swap templates-sdk and templates-sdk-dev files to enable redesign builds by default.
Change-Id: I9eabbbcd823fb29bd2209172c458cb9dad5f24d2
diff --git a/tools/droiddoc/templates-sdk/assets/js/docs.js b/tools/droiddoc/templates-sdk/assets/js/docs.js
index 7f4be4e..ca64217 100644
--- a/tools/droiddoc/templates-sdk/assets/js/docs.js
+++ b/tools/droiddoc/templates-sdk/assets/js/docs.js
@@ -82,7 +82,7 @@
.after('<hr/>');
// set up the search close button
- $('.search .close').click(function() {
+ $('#search-close').click(function() {
$searchInput = $('#search_autocomplete');
$searchInput.attr('value', '');
$(this).addClass("hide");
@@ -92,32 +92,6 @@
hideResults();
});
- // Set up quicknav
- var quicknav_open = false;
- $("#btn-quicknav").click(function() {
- if (quicknav_open) {
- $(this).removeClass('active');
- quicknav_open = false;
- collapse();
- } else {
- $(this).addClass('active');
- quicknav_open = true;
- expand();
- }
- })
-
- var expand = function() {
- $('#header-wrap').addClass('quicknav');
- $('#quicknav').stop().show().animate({opacity:'1'});
- }
-
- var collapse = function() {
- $('#quicknav').stop().animate({opacity:'0'}, 100, function() {
- $(this).hide();
- $('#header-wrap').removeClass('quicknav');
- });
- }
-
//Set up search
$("#search_autocomplete").focus(function() {
@@ -180,73 +154,71 @@
// Highlight the header tabs...
// highlight Design tab
- if ($("body").hasClass("design")) {
- $("#header li.design a").addClass("selected");
- $("#sticky-header").addClass("design");
+ var urlSegments = pagePathOriginal.split('/');
+ var navEl = $(".dac-nav-list");
+ var subNavEl = navEl.find(".dac-nav-secondary");
+ var parentNavEl;
+ if ($("body").hasClass("design")) {
+ navEl.find("> li.design > a").addClass("selected");
// highlight About tabs
} else if ($("body").hasClass("about")) {
- var rootDir = pagePathOriginal.substring(1,pagePathOriginal.indexOf('/', 1));
- if (rootDir == "about") {
- $("#nav-x li.about a").addClass("selected");
- } else if (rootDir == "wear") {
- $("#nav-x li.wear a").addClass("selected");
- } else if (rootDir == "tv") {
- $("#nav-x li.tv a").addClass("selected");
- } else if (rootDir == "auto") {
- $("#nav-x li.auto a").addClass("selected");
+ if (urlSegments[1] == "about" || urlSegments[1] == "wear" || urlSegments[1] == "tv" || urlSegments[1] == "auto") {
+ navEl.find("> li.home > a").addClass('has-subnav');
+ subNavEl.find("li." + urlSegments[1] + " > a").addClass("selected");
+ } else {
+ navEl.find("> li.home > a").addClass('selected');
}
// highlight Develop tab
} else if ($("body").hasClass("develop") || $("body").hasClass("google")) {
- $("#header li.develop a").addClass("selected");
- $("#sticky-header").addClass("develop");
+ parentNavEl = navEl.find("> li.develop > a");
+ parentNavEl.addClass('has-subnav');
+
// In Develop docs, also highlight appropriate sub-tab
- var rootDir = pagePathOriginal.substring(1,pagePathOriginal.indexOf('/', 1));
- if (rootDir == "training") {
- $("#nav-x li.training a").addClass("selected");
- } else if (rootDir == "guide") {
- $("#nav-x li.guide a").addClass("selected");
- } else if (rootDir == "reference") {
+ if (urlSegments[1] == "training") {
+ subNavEl.find("li.training > a").addClass("selected");
+ } else if (urlSegments[1] == "guide") {
+ subNavEl.find("li.guide > a").addClass("selected");
+ } else if (urlSegments[1] == "reference") {
// If the root is reference, but page is also part of Google Services, select Google
if ($("body").hasClass("google")) {
- $("#nav-x li.google a").addClass("selected");
+ subNavEl.find("li.google > a").addClass("selected");
} else {
- $("#nav-x li.reference a").addClass("selected");
+ subNavEl.find("li.reference > a").addClass("selected");
}
- } else if ((rootDir == "tools") || (rootDir == "sdk")) {
- $("#nav-x li.tools a").addClass("selected");
+ } else if ((urlSegments[1] == "tools") || (urlSegments[1] == "sdk")) {
+ subNavEl.find("li.tools > a").addClass("selected");
} else if ($("body").hasClass("google")) {
- $("#nav-x li.google a").addClass("selected");
+ subNavEl.find("li.google > a").addClass("selected");
} else if ($("body").hasClass("samples")) {
- $("#nav-x li.samples a").addClass("selected");
+ subNavEl.find("li.samples > a").addClass("selected");
+ } else {
+ parentNavEl.removeClass('has-subnav').addClass("selected");
}
-
// highlight Distribute tab
} else if ($("body").hasClass("distribute")) {
- $("#header li.distribute a").addClass("selected");
- $("#sticky-header").addClass("distribute");
+ parentNavEl = navEl.find("> li.distribute > a");
+ parentNavEl.addClass('has-subnav');
- var baseFrag = pagePathOriginal.indexOf('/', 1) + 1;
- var secondFrag = pagePathOriginal.substring(baseFrag, pagePathOriginal.indexOf('/', baseFrag));
- if (secondFrag == "users") {
- $("#nav-x li.users a").addClass("selected");
- } else if (secondFrag == "engage") {
- $("#nav-x li.engage a").addClass("selected");
- } else if (secondFrag == "monetize") {
- $("#nav-x li.monetize a").addClass("selected");
- } else if (secondFrag == "analyze") {
- $("#nav-x li.analyze a").addClass("selected");
- } else if (secondFrag == "tools") {
- $("#nav-x li.disttools a").addClass("selected");
- } else if (secondFrag == "stories") {
- $("#nav-x li.stories a").addClass("selected");
- } else if (secondFrag == "essentials") {
- $("#nav-x li.essentials a").addClass("selected");
- } else if (secondFrag == "googleplay") {
- $("#nav-x li.googleplay a").addClass("selected");
+ if (urlSegments[2] == "users") {
+ subNavEl.find("li.users > a").addClass("selected");
+ } else if (urlSegments[2] == "engage") {
+ subNavEl.find("li.engage > a").addClass("selected");
+ } else if (urlSegments[2] == "monetize") {
+ subNavEl.find("li.monetize > a").addClass("selected");
+ } else if (urlSegments[2] == "analyze") {
+ subNavEl.find("li.analyze > a").addClass("selected");
+ } else if (urlSegments[2] == "tools") {
+ subNavEl.find("li.disttools > a").addClass("selected");
+ } else if (urlSegments[2] == "stories") {
+ subNavEl.find("li.stories > a").addClass("selected");
+ } else if (urlSegments[2] == "essentials") {
+ subNavEl.find("li.essentials > a").addClass("selected");
+ } else if (urlSegments[2] == "googleplay") {
+ subNavEl.find("li.googleplay > a").addClass("selected");
+ } else {
+ parentNavEl.removeClass('has-subnav').addClass("selected");
}
- } else if ($("body").hasClass("about")) {
- $("#sticky-header").addClass("about");
}
// set global variable so we can highlight the sidenav a bit later (such as for google reference)
@@ -392,13 +364,12 @@
var $olClasses = $('<ol class="class-list"></ol>');
var $liClass;
- var $imgIcon;
var $h2Title;
var $pSummary;
var $olLessons;
var $liLesson;
$classLinks.each(function(index) {
- $liClass = $('<li></li>');
+ $liClass = $('<li class="clearfix"></li>');
$h2Title = $('<a class="title" href="'+$(this).attr('href')+'"><h2>' + $(this).html()+'</h2><span></span></a>');
$pSummary = $('<p class="description">' + $classDescriptions[index] + '</p>');
@@ -407,18 +378,14 @@
$lessons = $(this).closest('li').find('ul li a');
if ($lessons.length) {
- $imgIcon = $('<img src="'+toRoot+'assets/images/resource-tutorial.png" '
- + ' width="64" height="64" alt=""/>');
$lessons.each(function(index) {
$olLessons.append('<li><a href="'+$(this).attr('href')+'">' + $(this).html()+'</a></li>');
});
} else {
- $imgIcon = $('<img src="'+toRoot+'assets/images/resource-article.png" '
- + ' width="64" height="64" alt=""/>');
$pSummary.addClass('article');
}
- $liClass.append($h2Title).append($imgIcon).append($pSummary).append($olLessons);
+ $liClass.append($h2Title).append($pSummary).append($olLessons);
$olClasses.append($liClass);
});
$('.jd-descr').append($olClasses);
@@ -504,15 +471,6 @@
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
-
- // Revise the sidenav widths to make room for the scrollbar
- // which avoids the visible width from changing each time the bar appears
- var $sidenav = $("#side-nav");
- var sidenav_width = parseInt($sidenav.innerWidth());
-
- $("#devdoc-nav #nav").css("width", sidenav_width - 4 + "px"); // 4px is scrollbar width
-
-
$(".scroll-pane").removeAttr("tabindex"); // get rid of tabindex added by jscroller
if ($(".scroll-pane").length > 1) {
@@ -586,6 +544,15 @@
});
});
}
+
+ // Responsive testing
+ var responsiveParam = location.href.match(/[?&]responsive=?(|true|false)/);
+ if (responsiveParam) {
+ localStorage['test-responsive'] = ['', 'true'].indexOf(responsiveParam) > -1;
+ }
+ if (localStorage['test-responsive']) {
+ $(document.body).addClass('responsive');
+ }
});
// END of the onload event
@@ -738,21 +705,28 @@
/** Create the list of breadcrumb links in the sticky header */
function buildBreadcrumbs() {
- var $breadcrumbUl = $("#sticky-header ul.breadcrumb");
+ var $breadcrumbUl = $(".dac-header-crumbs");
+ var primaryNavLink = ".dac-nav-list > .dac-nav-item > .dac-nav-link";
+
// Add the secondary horizontal nav item, if provided
- var $selectedSecondNav = $("div#nav-x ul.nav-x a.selected").clone().removeClass("selected");
+ var $selectedSecondNav = $(".dac-nav-secondary .dac-nav-link.selected").clone()
+ .attr('class', 'dac-header-crumbs-link');
+
if ($selectedSecondNav.length) {
- $breadcrumbUl.prepend($("<li>").append($selectedSecondNav))
+ $breadcrumbUl.prepend($('<li class="dac-header-crumbs-item">').append($selectedSecondNav));
}
+
// Add the primary horizontal nav
- var $selectedFirstNav = $("div#header-wrap ul.nav-x a.selected").clone().removeClass("selected");
+ var $selectedFirstNav = $(primaryNavLink + ".selected, " + primaryNavLink + ".has-subnav").clone()
+ .attr('class', 'dac-header-crumbs-link');
+
// If there's no header nav item, use the logo link and title from alt text
if ($selectedFirstNav.length < 1) {
- $selectedFirstNav = $("<a>")
+ $selectedFirstNav = $('<a class="dac-header-crumbs-link">')
.attr('href', $("div#header .logo a").attr('href'))
.text($("div#header .logo img").attr('alt'));
}
- $breadcrumbUl.prepend($("<li>").append($selectedFirstNav));
+ $breadcrumbUl.prepend($('<li class="dac-header-crumbs-item">').append($selectedFirstNav));
}
@@ -824,7 +798,7 @@
function updateSideNavPosition() {
var newLeft = $(window).scrollLeft() - navBarLeftPos;
$('#devdoc-nav').css({left: -newLeft});
- $('#devdoc-nav .totop').css({left: -(newLeft - parseInt($('#side-nav').css('margin-left')))});
+ $('#devdoc-nav .totop').css({left: -(newLeft - parseInt($('#side-nav').css('padding-left')))});
}
// TODO: use $(document).ready instead
@@ -1068,7 +1042,7 @@
/* Sets the vertical scoll position at which the sticky bar should appear.
This method is called to reset the position when search results appear or hide */
function setStickyTop() {
- stickyTop = $('#header-wrapper').outerHeight() - $('#sticky-header').outerHeight();
+ stickyTop = $('#header-wrapper').outerHeight() - $('#header > .dac-header-inner').outerHeight();
}
/*
@@ -1078,8 +1052,7 @@
setStickyTop();
var hiding = false;
- var $stickyEl = $('#sticky-header');
- var $menuEl = $('.menu-container');
+ var $headerEl = $('#header');
// Exit if there's no sidenav
if ($('#side-nav').length == 0) return;
// Exit if the mouse target is a DIV, because that means the event is coming
@@ -1120,16 +1093,14 @@
.css({'width':'auto','margin':''})
.prependTo('#side-nav');
// delay hide the sticky
- $menuEl.removeClass('sticky-menu');
- $stickyEl.fadeOut(250);
+ $headerEl.removeClass('is-sticky');
hiding = false;
// update the sidenaav position for side scrolling
updateSideNavPosition();
} else if (!sticky && shouldBeSticky) {
sticky = true;
- $stickyEl.fadeIn(10);
- $menuEl.addClass('sticky-menu');
+ $headerEl.addClass('is-sticky');
// make the sidenav fixed
var width = $('#devdoc-nav').width();
@@ -1142,8 +1113,7 @@
updateSideNavPosition();
} else if (hiding && top < 15) {
- $menuEl.removeClass('sticky-menu');
- $stickyEl.hide();
+ $headerEl.removeClass('is-sticky');
hiding = false;
}
resizeNav(250); // pass true in order to delay the scrollbar re-initialization for performance
@@ -1841,12 +1811,11 @@
// if there are api results
if ((gMatches.length > 0) || (gGoogleMatches.length > 0)) {
// reveal suggestion list
- $('.suggest-card.dummy').show();
$('.suggest-card.reference').show();
var listIndex = 0; // list index position
// reset the lists
- $(".search_filtered_wrapper.reference li").remove();
+ $(".suggest-card.reference li").remove();
// ########### ANDROID RESULTS #############
if (gMatches.length > 0) {
@@ -1876,13 +1845,12 @@
}
} else {
$('.suggest-card.reference').hide();
- $('.suggest-card.dummy').hide();
}
// ########### JD DOC RESULTS #############
if (gDocsMatches.length > 0) {
// reset the lists
- $(".search_filtered_wrapper.docs li").remove();
+ $(".suggest-card:not(.reference) li").remove();
// determine google results to show
// NOTE: The order of the conditions below for the sugg.type MUST BE SPECIFIC:
@@ -1947,7 +1915,7 @@
}
} else {
- $('.search_filtered_wrapper.docs .suggest-card:not(.dummy)').hide(300);
+ $('.suggest-card:not(.reference)').hide(300);
}
}
@@ -1971,14 +1939,14 @@
// show/hide the close button
if (text != '') {
- $(".search .close").removeClass("hide");
+ $("#search-close").removeClass("hide");
} else {
- $(".search .close").addClass("hide");
+ $("#search-close").addClass("hide");
}
// 27 = esc
if (e.keyCode == 27) {
// close all search results
- if (kd) $('.search .close').trigger('click');
+ if (kd) $('#search-close').trigger('click');
return true;
}
// 13 = enter
@@ -2536,7 +2504,7 @@
{
if (!focused) {
if(obj.value == ""){
- $(".search .close").addClass("hide");
+ $("#search-close").addClass("hide");
}
$(".suggest-card").hide();
}
@@ -2553,7 +2521,7 @@
function hideResults() {
$("#searchResults").slideUp('fast', setStickyTop);
- $(".search .close").addClass("hide");
+ $("#search-close").addClass("hide");
location.hash = '';
$("#search_autocomplete").val("").blur();
@@ -2670,7 +2638,7 @@
} else {
// first time loading search results for this page
$('#searchResults').slideDown('slow', setStickyTop);
- $(".search .close").removeClass("hide");
+ $("#search-close").removeClass("hide");
loadSearchResults();
}
}, true);
@@ -2714,7 +2682,7 @@
searchControl.execute(query);
$('#searchResults').slideDown('slow', setStickyTop);
$("#search_autocomplete").focus();
- $(".search .close").removeClass("hide");
+ $("#search-close").removeClass("hide");
updateResultTitle(query);
});
@@ -3536,6 +3504,10 @@
var addedPageResources = {};
$(document).ready(function() {
+ // Need to initialize hero carousel before other sections for dedupe
+ // to work correctly.
+ $('[data-carousel-query]').dacCarouselQuery();
+
$('.resource-widget').each(function() {
initResourceWidget(this);
});
@@ -3545,8 +3517,8 @@
showing lines that are cut off. This works with the css ellipsis
classes to fade last text line and apply an ellipsis char. */
- //card text currently uses 15px line height.
- var lineHeight = 15;
+ //card text currently uses 20px line height.
+ var lineHeight = 20;
$('.card-info .text').ellipsisfade(lineHeight);
});
@@ -3562,11 +3534,10 @@
isCarousel = $widget.hasClass('resource-carousel-layout'),
isStack = $widget.hasClass('resource-stack-layout');
- // find size of widget by pulling out its class name
- var sizeCols = 1;
+ // remove illegal col-x class which is not relevant anymore thanks to responsive styles.
var m = $widget.get(0).className.match(/\bcol-(\d+)\b/);
- if (m) {
- sizeCols = parseInt(m[1], 10);
+ if (m && !$widget.is('.cols > *')) {
+ $widget.removeClass('col-' + m[1]);
}
var opts = {
@@ -3576,7 +3547,6 @@
sortOrder: $widget.data('sortorder'),
query: $widget.data('query'),
section: $widget.data('section'),
- sizeCols: sizeCols,
/* Added by LFL 6/6/14 */
resourceStyle: $widget.data('resourcestyle') || 'card',
stackSort: $widget.data('stacksort') || 'true'
@@ -3604,7 +3574,7 @@
/* Initializes a Resource Carousel Widget */
function drawResourcesCarouselWidget($widget, opts, resources) {
$widget.empty();
- var plusone = true; //always show plusone on carousel
+ var plusone = false; // stop showing plusone buttons on cards
$widget.addClass('resource-card slideshow-container')
.append($('<a>').addClass('slideshow-prev').text('Prev'))
@@ -3642,7 +3612,7 @@
function drawResourcesStackWidget($widget, opts, resources, sections) {
// Don't empty widget, grab all items inside since they will be the first
// items stacked, followed by the resource query
- var plusone = true; //by default show plusone on section cards
+ var plusone = false; // stop showing plusone buttons on cards
var cards = $widget.find('.resource-card').detach().toArray();
var numStacks = opts.numStacks || 1;
var $stacks = [];
@@ -3737,22 +3707,33 @@
return $el;
}
+
+ function createResponsiveFlowColumn(cardSize) {
+ var cardWidth = parseInt(cardSize.match(/(\d+)/)[1], 10);
+ var column = $('<div>').addClass('col-' + (cardWidth / 3) + 'of6');
+ if (cardWidth < 9) {
+ column.addClass('col-tablet-1of2');
+ } else if (cardWidth > 9 && cardWidth < 18) {
+ column.addClass('col-tablet-1of1');
+ }
+ if (cardWidth < 18) {
+ column.addClass('col-mobile-1of1')
+ }
+ return column;
+ }
/* Initializes a flow widget, see distribute.scss for generating accompanying css */
function drawResourcesFlowWidget($widget, opts, resources) {
- $widget.empty();
+ $widget.empty().addClass('cols');
var cardSizes = opts.cardSizes || ['6x6'];
var i = 0, j = 0;
- var plusone = true; // by default show plusone on resource cards
+ var plusone = false; // stop showing plusone buttons on cards
while (i < resources.length) {
var cardSize = cardSizes[j++ % cardSizes.length];
cardSize = cardSize.replace(/^\s+|\s+$/,'');
- // Some card sizes do not get a plusone button, such as where space is constrained
- // or for cards commonly embedded in docs (to improve overall page speed).
- plusone = !((cardSize == "6x2") || (cardSize == "6x3") ||
- (cardSize == "9x2") || (cardSize == "9x3") ||
- (cardSize == "12x2") || (cardSize == "12x3"));
+
+ var column = createResponsiveFlowColumn(cardSize).appendTo($widget);
// A stack has a third dimension which is the number of stacked items
var isStack = cardSize.match(/(\d+)x(\d+)x(\d+)/);
@@ -3763,7 +3744,7 @@
// Create a stack container which should have the dimensions defined
// by the product of the items inside.
$stackDiv = $('<div>').addClass('resource-card-stack resource-card-' + isStack[1]
- + 'x' + isStack[2] * isStack[3]) .appendTo($widget);
+ + 'x' + isStack[2] * isStack[3]) .appendTo(column);
}
// Build each stack item or just a single item
@@ -3785,7 +3766,7 @@
stackCount = 0;
}
- $card.appendTo($stackDiv || $widget);
+ $card.appendTo($stackDiv || column);
} while (++i < resources.length && stackCount > 0);
}
@@ -3800,6 +3781,10 @@
}
function buildResourceList(opts) {
+ return $.queryResources(opts);
+ }
+
+ $.queryResources = function(opts) {
var maxResults = opts.maxResults || 100;
var query = opts.query || '';
@@ -3848,8 +3833,9 @@
// add to list of already added indices
for (var j = 0; j < resources.length; j++) {
- // console.log(resources[j].title);
- addedResourceIndices[resources[j].index] = 1;
+ if (resources[j]) {
+ addedResourceIndices[resources[j].index] = 1;
+ }
}
// concat to final results list
@@ -3891,7 +3877,7 @@
function getResourceNotAlreadyAddedFilter(addedResourceIndices) {
return function(resource) {
- return !addedResourceIndices[resource.index];
+ return resource && !addedResourceIndices[resource.index];
};
}
@@ -4155,7 +4141,7 @@
$this.parent().siblings().each(function ()
{
if ($(this).is(":visible")) {
- var h = $(this).height();
+ var h = $(this).outerHeight(true);
remainingHeight = remainingHeight - h;
}
});
@@ -4354,3 +4340,467 @@
}
}
})();
+
+(function($) {
+ 'use strict';
+
+ /**
+ * Toggle Floating Label state.
+ * @param {HTMLElement} el - The DOM element.
+ * @param options
+ * @constructor
+ */
+ function FloatingLabel(el, options) {
+ this.el = $(el);
+ this.options = $.extend({}, FloatingLabel.DEFAULTS_, options);
+ this.group = this.el.closest('.dac-form-input-group');
+ this.input = this.group.find('.dac-form-input');
+
+ this.checkValue_ = this.checkValue_.bind(this);
+ this.checkValue_();
+
+ this.input.on('focus', function() {
+ this.group.addClass('dac-focused');
+ }.bind(this));
+ this.input.on('blur', function() {
+ this.group.removeClass('dac-focused');
+ this.checkValue_();
+ }.bind(this));
+ this.input.on('keyup', this.checkValue_);
+ }
+
+ /**
+ * The label is moved out of the textbox when it has a value.
+ */
+ FloatingLabel.prototype.checkValue_ = function() {
+ if (this.input.val().length) {
+ this.group.addClass('dac-has-value');
+ } else {
+ this.group.removeClass('dac-has-value');
+ }
+ };
+
+ /**
+ * jQuery plugin
+ * @param {object} options - Override default options.
+ */
+ $.fn.dacFloatingLabel = function(options) {
+ return this.each(function() {
+ new FloatingLabel(this, options);
+ });
+ };
+
+ $(document).on('ready.aranja', function() {
+ $('.dac-form-floatlabel').each(function() {
+ $(this).dacFloatingLabel($(this).data());
+ });
+ });
+})(jQuery);
+
+/* global toRoot, CAROUSEL_OVERRIDE */
+(function($) {
+ // Ordering matters
+ var TAG_MAP = [
+ {from: 'developerstory', to: 'Android Developer Story'},
+ {from: 'googleplay', to: 'Google Play'}
+ ];
+
+ function DacCarouselQuery(el) {
+ this.el = $(el);
+
+ var opts = this.el.data();
+ opts.maxResults = parseInt(opts.maxResults || '100', 10);
+ opts.query = opts.carouselQuery;
+ var resources = $.queryResources(opts);
+
+ this.el.empty();
+ $(resources).map(function() {
+ var resource = $.extend({}, this, CAROUSEL_OVERRIDE[this.url]);
+ var slide = $('<article class="dac-expand dac-hero">');
+ var image = cleanUrl(resource.heroImage || resource.image);
+ var fullBleed = image && !resource.heroColor;
+
+ // Configure background
+ slide.css({
+ backgroundImage: fullBleed ? 'url(' + image + ')' : '',
+ backgroundColor: resource.heroColor || ''
+ });
+
+ // Should copy be inverted
+ slide.toggleClass('dac-invert', resource.heroInvert || fullBleed);
+ slide.toggleClass('dac-darken', fullBleed);
+
+ var cols = $('<div class="cols dac-hero-content">');
+
+ // inline image column
+ var rightCol = $('<div class="col-1of2 col-push-1of2 dac-hero-figure">')
+ .appendTo(cols);
+
+ if (!fullBleed && image) {
+ rightCol.append($('<img>').attr('src', image));
+ }
+
+ // info column
+ $('<div class="col-1of2 col-pull-1of2">')
+ .append($('<div class="dac-hero-tag">').text(formatTag(resource)))
+ .append($('<h1 class="dac-hero-title">').text(formatTitle(resource)))
+ .append($('<p class="dac-hero-description">').text(resource.summary))
+ .append($('<a class="dac-hero-cta">')
+ .text(formatCTA(resource))
+ .attr('href', cleanUrl(resource.url))
+ .prepend($('<span class="dac-sprite dac-auto-chevron">'))
+ )
+ .appendTo(cols);
+
+ slide.append(cols.wrap('<div class="wrap">').parent());
+ return slide[0];
+ }).prependTo(this.el);
+
+ // Pagination element.
+ this.el.append('<div class="dac-hero-carousel-pagination"><div class="wrap" data-carousel-pagination>');
+
+ this.el.dacCarousel();
+ }
+
+ function cleanUrl(url) {
+ if (url && url.indexOf('//') === -1) {
+ url = toRoot + url;
+ }
+ return url;
+ }
+
+ function formatTag(resource) {
+ // Hmm, need a better more scalable solution for this.
+ for (var i = 0, mapping; mapping = TAG_MAP[i]; i++) {
+ if (resource.tags.indexOf(mapping.from) > -1) {
+ return mapping.to;
+ }
+ }
+ return resource.type;
+ }
+
+ function formatTitle(resource) {
+ return resource.title.replace(/android developer story: /i, '');
+ }
+
+ function formatCTA(resource) {
+ return resource.type === 'youtube' ? 'Watch the video' : 'Learn more';
+ }
+
+ // jQuery plugin
+ $.fn.dacCarouselQuery = function() {
+ return this.each(function() {
+ var el = $(this);
+ var data = el.data('dac.carouselQuery');
+
+ if (!data) { el.data('dac.carouselQuery', (data = new DacCarouselQuery(el))); }
+ });
+ };
+
+ // Data API
+ $(function() {
+ $('[data-carousel-query]').dacCarouselQuery();
+ });
+})(jQuery);
+
+(function($) {
+ /**
+ * A CSS based carousel, inspired by SequenceJS.
+ * @param {jQuery} el
+ * @param {object} options
+ * @constructor
+ */
+ function DacCarousel(el, options) {
+ this.el = $(el);
+ this.options = options = $.extend({}, DacCarousel.OPTIONS, this.el.data(), options || {});
+ this.frames = this.el.find(options.frameSelector);
+ this.count = this.frames.size();
+ this.current = options.start;
+
+ this.initPagination();
+ this.initEvents();
+ this.initFrame();
+ }
+
+ DacCarousel.OPTIONS = {
+ auto: true,
+ autoTime: 10000,
+ autoMinTime: 5000,
+ btnPrev: '[data-carousel-prev]',
+ btnNext: '[data-carousel-next]',
+ frameSelector: 'article',
+ loop: true,
+ start: 0,
+ pagination: '[data-carousel-pagination]'
+ };
+
+ DacCarousel.prototype.initPagination = function() {
+ this.pagination = $([]);
+ if (!this.options.pagination) { return; }
+
+ var pagination = $('<ul class="dac-pagination">');
+ var parent = this.el;
+ if (typeof this.options.pagination === 'string') { parent = this.el.find(this.options.pagination); }
+
+ if (this.count > 1) {
+ for (var i = 0; i < this.count; i++) {
+ var li = $('<li class="dac-pagination-item">').text(i);
+ if (i === this.options.start) { li.addClass('active'); }
+ li.click(this.go.bind(this, i));
+
+ pagination.append(li);
+ }
+ this.pagination = pagination.children();
+ parent.append(pagination);
+ }
+ };
+
+ DacCarousel.prototype.initEvents = function() {
+ var that = this;
+
+ this.el.hover(function() {
+ that.pauseRotateTimer();
+ }, function() {
+ that.startRotateTimer();
+ });
+
+ $(this.options.btnPrev).click(function(e) {
+ e.preventDefault();
+ that.prev();
+ });
+
+ $(this.options.btnNext).click(function(e) {
+ e.preventDefault();
+ that.next();
+ });
+ };
+
+ DacCarousel.prototype.initFrame = function() {
+ this.frames.removeClass('active').eq(this.options.start).addClass('active');
+ };
+
+ DacCarousel.prototype.startRotateTimer = function() {
+ if (!this.options.auto || this.rotateTimer) { return; }
+ this.rotateTimer = setTimeout(this.next.bind(this), this.options.autoTime);
+ };
+
+ DacCarousel.prototype.pauseRotateTimer = function() {
+ clearTimeout(this.rotateTimer);
+ this.rotateTimer = null;
+ };
+
+ DacCarousel.prototype.prev = function() {
+ this.go(this.current - 1);
+ };
+
+ DacCarousel.prototype.next = function() {
+ this.go(this.current + 1);
+ };
+
+ DacCarousel.prototype.go = function(next) {
+ // Figure out what the next slide is.
+ while (this.count > 0 && next >= this.count) { next -= this.count; }
+ while (next < 0) { next += this.count; }
+
+ // Cancel if we're already on that slide.
+ if (next === this.current) { return; }
+
+ // Prepare next slide.
+ this.frames.eq(next).removeClass('out');
+
+ // Recalculate styles before starting slide transition.
+ var that = this;
+ resolveStyles(this.el[0], function() {
+ // Update pagination
+ that.pagination.removeClass('active').eq(next).addClass('active');
+
+ // Transition out current frame
+ that.frames.eq(that.current).toggleClass('active out');
+
+ // Transition in a new frame
+ that.frames.eq(next).toggleClass('active');
+
+ that.current = next;
+ });
+ };
+
+ // Helper
+ function resolveStyles(el, callback) {
+ /*jshint expr:true*/
+ el.offsetTop;
+ callback();
+ }
+
+ // jQuery plugin
+ $.fn.dacCarousel = function() {
+ this.each(function() {
+ var $el = $(this);
+ $el.data('dac-carousel', new DacCarousel(this));
+ });
+ return this;
+ };
+
+ // Data API
+ $(function() {
+ $('[data-carousel]').dacCarousel();
+ });
+})(jQuery);
+
+(function($) {
+ 'use strict';
+
+ /**
+ * Toggle the visabilty of the mobile navigation.
+ * @param {HTMLElement} el - The DOM element.
+ * @param options
+ * @constructor
+ */
+ function ToggleModal(el, options) {
+ this.el = $(el);
+ this.options = $.extend({}, ToggleModal.DEFAULTS_, options);
+ this.el.on('click', this.clickHandler_.bind(this));
+ }
+
+ ToggleModal.DEFAULTS_ = {
+ toggleClass: 'dac-modal-open'
+ };
+
+ /**
+ * The actual toggle logic.
+ * @param event
+ * @private
+ */
+ ToggleModal.prototype.clickHandler_ = function(event) {
+ event.preventDefault();
+ //TODO: Toggle a class on the modal itself
+ $('body').toggleClass(this.options.toggleClass);
+ $('.dac-modal-dimmer').toggleClass('dac-active');
+ $('.dac-modal-window').toggleClass('dac-active');
+ };
+
+ /**
+ * jQuery plugin
+ * @param {object} options - Override default options.
+ */
+ $.fn.dacToggleModal = function(options) {
+ return this.each(function() {
+ new ToggleModal(this, options);
+ });
+ };
+
+ /**
+ * Data Attribute API
+ */
+ $(document).on('ready.aranja', function() {
+ $('[data-modal-toogle]').each(function() {
+ $(this).dacToggleModal($(this).data());
+ });
+ });
+})(jQuery);
+
+(function($) {
+ 'use strict';
+
+ /**
+ * Toggle the visabilty of the mobile navigation.
+ * @param {HTMLElement} el - The DOM element.
+ * @param options
+ * @constructor
+ */
+ function ToggleNav(el, options) {
+ this.el = $(el);
+ this.options = $.extend({}, ToggleNav.DEFAULTS_, options);
+ this.options.target = [this.options.navigation];
+
+ if (this.options.body) {this.options.target.push('body')}
+ if (this.options.dimmer) {this.options.target.push(this.options.dimmer)}
+
+ this.el.on('click', this.clickHandler_.bind(this));
+ }
+
+ /**
+ * ToggleNav Default Settings
+ * @type {{body: boolean, dimmer: string, navigation: string, toggleClass: string}}
+ * @private
+ */
+ ToggleNav.DEFAULTS_ = {
+ body: true,
+ dimmer: '.dac-nav-dimmer',
+ navigation: '[data-dac-nav]',
+ toggleClass: 'dac-nav-open'
+ };
+
+ /**
+ * The actual toggle logic.
+ * @param event
+ * @private
+ */
+ ToggleNav.prototype.clickHandler_ = function(event) {
+ event.preventDefault();
+ $(this.options.target.join(', ')).toggleClass(this.options.toggleClass);
+ };
+
+ /**
+ * jQuery plugin
+ * @param {object} options - Override default options.
+ */
+ $.fn.dacToggleMobileNav = function(options) {
+ return this.each(function() {
+ new ToggleNav(this, options);
+ });
+ };
+
+ /**
+ * Data Attribute API
+ */
+ $(window).on('load.aranja', function() {
+ $('[data-dac-toggle-nav]').each(function() {
+ $(this).dacToggleMobileNav($(this).data());
+ });
+ });
+})(jQuery);
+
+(function($) {
+ 'use strict';
+
+ /**
+ * Submit the newsletter form to a Google Form.
+ * @param {HTMLElement} el - The Form DOM element.
+ * @constructor
+ */
+ function NewsletterForm(el) {
+ this.el = $(el);
+ this.url = this.el.attr('action');
+ this.el.on('submit', this.submitHandler_.bind(this));
+ }
+
+ /**
+ * Close the modal when the form is sent.
+ * @private
+ */
+ NewsletterForm.prototype.submitHandler_ = function() {
+ //TODO: Close the modal with an event and let modal.js handle this
+ $('body').removeClass('dac-modal-open');
+ $('.dac-modal-dimmer').removeClass('dac-active');
+ $('.dac-modal-window').removeClass('dac-active');
+ };
+
+ /**
+ * jQuery plugin
+ * @param {object} options - Override default options.
+ */
+ $.fn.dacNewsletterForm = function(options) {
+ return this.each(function() {
+ new NewsletterForm(this, options);
+ });
+ };
+
+ /**
+ * Data Attribute API
+ */
+ $(document).on('ready.aranja', function() {
+ $('[data-newsletter-form]').each(function() {
+ $(this).dacNewsletterForm();
+ });
+ });
+})(jQuery);