Skip to content

Cleanup doc embed js #1507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 31, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 8 additions & 27 deletions readthedocs/api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
from readthedocs.builds.models import Build, Version
from readthedocs.core.utils import trigger_build
from readthedocs.projects.models import Project, ImportedFile
from readthedocs.projects.version_handling import highest_version
from readthedocs.projects.version_handling import parse_version_failsafe
from readthedocs.restapi.views.footer_views import get_version_compare_data

from .utils import SearchMixin, PostAuthentication

Expand Down Expand Up @@ -144,34 +143,16 @@ def get_object_list(self, request):
self._meta.queryset = Version.objects.api(user=request.user, only_active=False)
return super(VersionResource, self).get_object_list(request)

def version_compare(self, request, **kwargs):
project = get_object_or_404(Project, slug=kwargs['project_slug'])
highest_version_obj, highest_version_comparable = highest_version(
project.versions.filter(active=True))
base = kwargs.get('base', None)
ret_val = {
'project': highest_version_obj,
'version': highest_version_comparable,
'is_highest': True,
}
if highest_version_obj:
ret_val['url'] = highest_version_obj.get_absolute_url()
ret_val['slug'] = highest_version_obj.slug,
def version_compare(self, request, project_slug, base=None, **kwargs):
project = get_object_or_404(Project, slug=project_slug)
if base and base != LATEST:
try:
base_version_obj = project.versions.get(slug=base)
base_version_comparable = parse_version_failsafe(
base_version_obj.verbose_name)
if base_version_comparable:
# This is only place where is_highest can get set. All
# error cases will be set to True, for non- standard
# versions.
ret_val['is_highest'] = (
base_version_comparable >= highest_version_comparable)
else:
ret_val['is_highest'] = True
base_version = project.versions.get(slug=base)
except (Version.DoesNotExist, TypeError):
ret_val['is_highest'] = True
base_version = None
else:
base_version = None
ret_val = get_version_compare_data(project, base_version)
return self.create_response(request, ret_val)

def build_version(self, request, **kwargs):
Expand Down
102 changes: 102 additions & 0 deletions readthedocs/core/static-src/core/js/doc-embed/footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
var Build = require('./build').Build;
var rtddata = require('./rtd-data');
var versionCompare = require('./version-compare');


function init() {
var rtd = rtddata.get();

var get_data = {
project: rtd['project'],
version: rtd['version'],
page: rtd['page'],
theme: rtd['theme'],
format: "jsonp",
};

// Crappy heuristic, but people change the theme name on us.
// So we have to do some duck typing.
if ("docroot" in rtd) {
get_data['docroot'] = rtd['docroot'];
}

if ("source_suffix" in rtd) {
get_data['source_suffix'] = rtd['source_suffix'];
}

if (window.location.pathname.indexOf('/projects/') === 0) {
get_data['subproject'] = true;
}

// Get footer HTML from API and inject it into the page.
$.ajax({
url: rtd.api_host + "/api/v2/footer_html/",
crossDomain: true,
xhrFields: {
withCredentials: true,
},
dataType: "jsonp",
data: get_data,
success: function (data) {
versionCompare.init(data.version_compare);
injectFooter(data);
setupBookmarkCSRFToken();
},
error: function () {
console.error('Error loading Read the Docs footer');
}
});
}


function injectFooter(data) {
var build = new Build(rtddata.get());

// If the theme looks like ours, update the existing badge
// otherwise throw a a full one into the page.
if (build.is_rtd_theme()) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build doesn't exist here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argh :( that's addressed now.

$("div.rst-other-versions").html(data['html']);
} else {
$("body").append(data['html']);
}

if (!data['version_active']) {
$('.rst-current-version').addClass('rst-out-of-date');
} else if (!data['version_supported']) {
//$('.rst-current-version').addClass('rst-active-old-version')
}

// Show promo selectively
if (data.promo && build.show_promo()) {
var promo = new sponsorship.Promo(
data.promo_data.id,
data.promo_data.text,
data.promo_data.link,
data.promo_data.image
)
if (promo) {
promo.display();
}
}
}


function setupBookmarkCSRFToken() {
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", $('a.bookmark[token]').attr('token'));
}
}
});
}


module.exports = {
init: init
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function init() {
// Add Grok the Docs Client
$.ajax({
url: "https://api.grokthedocs.com/static/javascript/bundle-client.js",
crossDomain: true,
dataType: "script",
});
}


module.exports = {
init: init
};
52 changes: 52 additions & 0 deletions readthedocs/core/static-src/core/js/doc-embed/mkdocs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Mkdocs specific JS code.
*/


var rtddata = require('./rtd-data');


function init() {
var rtd = rtddata.get();

// Override MkDocs styles
if ("builder" in rtd && rtd["builder"] == "mkdocs") {
$('<input>').attr({
type: 'hidden',
name: 'project',
value: rtd["project"]
}).appendTo('#rtd-search-form');
$('<input>').attr({
type: 'hidden',
name: 'version',
value: rtd["version"]
}).appendTo('#rtd-search-form');
$('<input>').attr({
type: 'hidden',
name: 'type',
value: 'file'
}).appendTo('#rtd-search-form');

$("#rtd-search-form").prop("action", rtd.api_host + "/elasticsearch/");

// Apply stickynav to mkdocs builds
var nav_bar = $('nav.wy-nav-side:first'),
win = $(window),
sticky_nav_class = 'stickynav',
apply_stickynav = function () {
if (nav_bar.height() <= win.height()) {
nav_bar.addClass(sticky_nav_class);
} else {
nav_bar.removeClass(sticky_nav_class);
}
};
win.on('resize', apply_stickynav);
apply_stickynav();
}

}


module.exports = {
init: init
};
21 changes: 21 additions & 0 deletions readthedocs/core/static-src/core/js/doc-embed/rtd-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* This exposes data injected during the RTD build into the template. It's
* provided via the global READTHEDOCS_DATA variable and is exposed here as a
* module for cleaner usage.
*/


/*
* Access READTHEDOCS_DATA on call, not on module load. The reason is that the
* READTHEDOCS_DATA might not be available during script load time.
*/
function get() {
return $.extend({
api_host: 'https://readthedocs.org'
}, window.READTHEDOCS_DATA);
}


module.exports = {
get: get
};
143 changes: 143 additions & 0 deletions readthedocs/core/static-src/core/js/doc-embed/sphinx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* Sphinx builder specific JS code.
*/


var rtddata = require('./rtd-data');


function init() {
var rtd = rtddata.get();

/// Click tracking on flyout
$(document).on('click', "[data-toggle='rst-current-version']", function() {
var flyout_state = $("[data-toggle='rst-versions']").hasClass('shift-up') ? 'was_open' : 'was_closed'
if (_gaq) {
_gaq.push(
['rtfd._setAccount', 'UA-17997319-1'],
['rtfd._trackEvent', 'Flyout', 'Click', flyout_state]
);
}
});

/// Read the Docs Sphinx theme code
if (!("builder" in rtd) || "builder" in rtd && rtd["builder"] != "mkdocs") {
function toggleCurrent (elem) {
var parent_li = elem.closest('li');
parent_li.siblings('li.current').removeClass('current');
parent_li.siblings().find('li.current').removeClass('current');
parent_li.find('> ul li.current').removeClass('current');
parent_li.toggleClass('current');
}

// Shift nav in mobile when clicking the menu.
$(document).on('click', "[data-toggle='wy-nav-top']", function() {
$("[data-toggle='wy-nav-shift']").toggleClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
});
// Nav menu link click operations
$(document).on('click', ".wy-menu-vertical .current ul li a", function() {
var target = $(this);
// Close menu when you click a link.
$("[data-toggle='wy-nav-shift']").removeClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
// Handle dynamic display of l3 and l4 nav lists
toggleCurrent(target);
if (typeof(window.SphinxRtdTheme) != 'undefined') {
window.SphinxRtdTheme.StickyNav.hashChange();
}
});
$(document).on('click', "[data-toggle='rst-current-version']", function() {
$("[data-toggle='rst-versions']").toggleClass("shift-up");
});
// Make tables responsive
$("table.docutils:not(.field-list)").wrap("<div class='wy-table-responsive'></div>");

// Add expand links to all parents of nested ul
$('.wy-menu-vertical ul').siblings('a').each(function () {
var link = $(this);
expand = $('<span class="toctree-expand"></span>');
expand.on('click', function (ev) {
toggleCurrent(link);
ev.stopPropagation();
return false;
});
link.prepend(expand);
});

// Sphinx theme state
window.SphinxRtdTheme = (function (jquery) {
var stickyNav = (function () {
var navBar,
win,
winScroll = false,
linkScroll = false,
winPosition = 0,
enable = function () {
init();
reset();
win.on('hashchange', reset);

// Set scrolling
win.on('scroll', function () {
if (!linkScroll) {
winScroll = true;
}
});
setInterval(function () {
if (winScroll) {
winScroll = false;
var newWinPosition = win.scrollTop(),
navPosition = navBar.scrollTop(),
newNavPosition = navPosition + (newWinPosition - winPosition);
navBar.scrollTop(newNavPosition);
winPosition = newWinPosition;
}
}, 25);
},
init = function () {
navBar = jquery('nav.wy-nav-side:first');
win = jquery(window);
},
reset = function () {
// Get anchor from URL and open up nested nav
var anchor = encodeURI(window.location.hash);
if (anchor) {
try {
var link = $('.wy-menu-vertical')
.find('[href="' + anchor + '"]');
$('.wy-menu-vertical li.toctree-l1 li.current')
.removeClass('current');
link.closest('li.toctree-l2').addClass('current');
link.closest('li.toctree-l3').addClass('current');
link.closest('li.toctree-l4').addClass('current');
}
catch (err) {
console.log("Error expanding nav for anchor", err);
}
}
},
hashChange = function () {
linkScroll = true;
win.one('hashchange', function () {
linkScroll = false;
});
};
jquery(init);
return {
enable: enable,
hashChange: hashChange
};
}());
return {
StickyNav: stickyNav
};
}($));
}

}


module.exports = {
init: init
};
Loading