From 13c53c4ecd56741746b670b768ce72b51116bdb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gregor=20M=C3=BCllegger?= Date: Thu, 6 Aug 2015 12:55:58 +0200 Subject: [PATCH] Fix sphinx_rtd_theme theme override in embed js The last refactor wasn't aware of the fact that the js Build class was modifying the actual config object in place. We are fixing this by using a getter method were the value is needed and are not mutating the original config object in place. Fixes #1542. --- .../static-src/core/js/doc-embed/build.js | 36 -- .../static-src/core/js/doc-embed/footer.js | 9 +- .../static-src/core/js/doc-embed/rtd-data.js | 40 +- .../core/static/core/js/autocomplete.js | 15 +- .../static/core/js/readthedocs-doc-embed.js | 547 +----------------- 5 files changed, 44 insertions(+), 603 deletions(-) delete mode 100644 readthedocs/core/static-src/core/js/doc-embed/build.js diff --git a/readthedocs/core/static-src/core/js/doc-embed/build.js b/readthedocs/core/static-src/core/js/doc-embed/build.js deleted file mode 100644 index 66c55ae773f..00000000000 --- a/readthedocs/core/static-src/core/js/doc-embed/build.js +++ /dev/null @@ -1,36 +0,0 @@ -// Documentation build state - -module.exports = { - Build: Build -}; - -function Build (config) { - this.config = config; - - // Crappy heuristic, but people change the theme name on us. So we have to - // do some duck typing. - if (this.config['theme'] != 'sphinx_rtd_theme') { - if ($('div.rst-other-versions').length == 1) { - this.config['theme'] = 'sphinx_rtd_theme'; - } - } - - if (this.config['api_host'] == undefined) { - this.config['api_host'] = 'https://readthedocs.org'; - } -} - -Build.prototype.is_rtd_theme = function () { - return (this.config['theme'] == 'sphinx_rtd_theme'); -}; - -Build.prototype.is_sphinx_builder = function () { - return (!('builder' in this.config) || this.config['builder'] != 'mkdocs'); -}; - -Build.prototype.show_promo = function () { - return (this.config['api_host'] != 'https://readthedocs.com' - && this.is_sphinx_builder() - && this.is_rtd_theme() - ); -}; diff --git a/readthedocs/core/static-src/core/js/doc-embed/footer.js b/readthedocs/core/static-src/core/js/doc-embed/footer.js index f7d10eb45f6..6fd99cc440f 100644 --- a/readthedocs/core/static-src/core/js/doc-embed/footer.js +++ b/readthedocs/core/static-src/core/js/doc-embed/footer.js @@ -1,4 +1,3 @@ -var Build = require('./build').Build; var rtddata = require('./rtd-data'); var versionCompare = require('./version-compare'); @@ -10,7 +9,7 @@ function init() { project: rtd['project'], version: rtd['version'], page: rtd['page'], - theme: rtd['theme'], + theme: rtd.get_theme_name(), format: "jsonp", }; @@ -50,11 +49,11 @@ function init() { function injectFooter(data) { - var build = new Build(rtddata.get()); + var config = 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()) { + if (config.is_rtd_theme()) { $("div.rst-other-versions").html(data['html']); } else { $("body").append(data['html']); @@ -67,7 +66,7 @@ function injectFooter(data) { } // Show promo selectively - if (data.promo && build.show_promo()) { + if (data.promo && config.show_promo()) { var promo = new sponsorship.Promo( data.promo_data.id, data.promo_data.text, diff --git a/readthedocs/core/static-src/core/js/doc-embed/rtd-data.js b/readthedocs/core/static-src/core/js/doc-embed/rtd-data.js index aff57f98f17..21678b81905 100644 --- a/readthedocs/core/static-src/core/js/doc-embed/rtd-data.js +++ b/readthedocs/core/static-src/core/js/doc-embed/rtd-data.js @@ -5,14 +5,50 @@ */ +var configMethods = { + is_rtd_theme: function () { + return this.get_theme_name() === 'sphinx_rtd_theme'; + }, + + is_sphinx_builder: function () { + return (!('builder' in this) || this.builder != 'mkdocs'); + }, + + get_theme_name: function () { + // Crappy heuristic, but people change the theme name on us. So we have to + // do some duck typing. + if (this.theme !== 'sphinx_rtd_theme') { + if ($('div.rst-other-versions').length === 1) { + return 'sphinx_rtd_theme'; + } + } + return this.theme; + }, + + show_promo: function () { + return ( + this.api_host !== 'https://readthedocs.com' && + this.is_sphinx_builder() && + this.is_rtd_theme()); + } +}; + + /* * 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({ + // Make `methods` the prototype. + var config = Object.create(configMethods); + + var defaults = { api_host: 'https://readthedocs.org' - }, window.READTHEDOCS_DATA); + }; + + $.extend(config, defaults, window.READTHEDOCS_DATA); + + return config; } diff --git a/readthedocs/core/static/core/js/autocomplete.js b/readthedocs/core/static/core/js/autocomplete.js index 328bc608050..0907e747b53 100644 --- a/readthedocs/core/static/core/js/autocomplete.js +++ b/readthedocs/core/static/core/js/autocomplete.js @@ -1,14 +1 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o').attr({ - type: 'hidden', - name: 'project', - value: rtd["project"] - }).appendTo('#rtd-search-form'); - $('').attr({ - type: 'hidden', - name: 'version', - value: rtd["version"] - }).appendTo('#rtd-search-form'); - $('').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 -}; - -},{"./rtd-data":5}],5:[function(require,module,exports){ -/* - * 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 -}; - -},{}],6:[function(require,module,exports){ -/* - * 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("
"); - - // Add expand links to all parents of nested ul - $('.wy-menu-vertical ul').siblings('a').each(function () { - var link = $(this); - expand = $(''); - 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 -}; - -},{"./rtd-data":5}],7:[function(require,module,exports){ -var rtddata = require('./rtd-data'); - - -function init(data) { - var rtd = rtddata.get(); - - /// Out of date message - - if (data.is_highest) { - return; - } - - var currentURL = window.location.pathname.replace(rtd['version'], data.slug); - var warning = $( - '
' + - '

Note

' + - '

' + - 'You are not using the most up to date version of the library. ' + - ' is the newest version.' + - '

' + - '
'); - - warning - .find('a') - .attr('href', currentURL) - .text(data.version); - - var body = $("div.body"); - if (!body.length) { - body = $("div.document"); - } - body.prepend(warning); -} - - -module.exports = { - init: init -}; - -},{"./rtd-data":5}],8:[function(require,module,exports){ -var sponsorship = require('./sponsorship'), - footer = require('./doc-embed/footer.js'), - grokthedocs = require('./doc-embed/grokthedocs-client'), - mkdocs = require('./doc-embed/mkdocs'), - rtddata = require('./doc-embed/rtd-data'), - sphinx = require('./doc-embed/sphinx'); - -$(document).ready(function () { - footer.init(); - sphinx.init(); - grokthedocs.init(); - mkdocs.init(); -}); - -},{"./doc-embed/footer.js":2,"./doc-embed/grokthedocs-client":3,"./doc-embed/mkdocs":4,"./doc-embed/rtd-data":5,"./doc-embed/sphinx":6,"./sponsorship":9}],9:[function(require,module,exports){ -/* Read the Docs - Documentation promotions */ - -var $ = window.$; - -module.exports = { - Promo: Promo -}; - -function Promo (id, text, link, image) { - this.id = id; - this.text = text; - this.link = link; - this.image = image; - this.promo = null; -} - -Promo.prototype.create = function () { - var self = this, - nav_side = $('nav.wy-nav-side'); - - if (nav_side.length) { - // Add elements - promo = $('
') - .attr('class', 'wy-menu rst-pro'); - - // Promo info - var promo_about = $('
') - .attr('class', 'rst-pro-about'); - var promo_about_link = $('') - .attr('href', 'http://docs.readthedocs.org/en/latest/sponsors.html#sponsorship-information') - .appendTo(promo_about); - var promo_about_icon = $('') - .attr('class', 'fa fa-info-circle') - .appendTo(promo_about_link); - promo_about.appendTo(promo); - - // On Click handler - function promo_click() { - if (_gaq) { - _gaq.push( - ['rtfd._setAccount', 'UA-17997319-1'], - ['rtfd._trackEvent', 'Promo', 'Click', self.id] - ); - } - } - - // Promo image - if (self.image) { - var promo_image_link = $('') - .attr('class', 'rst-pro-image-wrapper') - .attr('href', self.link) - .attr('target', '_blank') - .on('click', promo_click); - var promo_image = $('') - .attr('class', 'rst-pro-image') - .attr('src', self.image) - .appendTo(promo_image_link); - promo.append(promo_image_link); - } - - // Create link with callback - var promo_text = $('') - .html(self.text); - $(promo_text).find('a').each(function () { - $(this) - .attr('class', 'rst-pro-link') - .attr('href', self.link) - .attr('target', '_blank') - .on('click', promo_click); - }); - promo.append(promo_text); - - promo.appendTo(nav_side); - - promo.wrapper = $('
') - .attr('class', 'rst-pro-wrapper') - .appendTo(nav_side); - - return promo; - } -} - -// Position promo -Promo.prototype.display = function () { - var promo = this.promo, - self = this; - - if (! promo) { - promo = this.promo = this.create(); - } - promo.show(); -} - -Promo.prototype.disable = function () { -} - -// Variant factory method -Promo.from_variants = function (variants) { - if (variants.length == 0) { - return null; - } - var chosen = Math.floor(Math.random() * variants.length), - variant = variants[chosen], - text = variant.text, - link = variant.link, - image = variant.image, - id = variant.id; - return new Promo(id, text, link, image); -}; - -},{}]},{},[8]); +!function t(e,r,o){function n(a,s){if(!r[a]){if(!e[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(i)return i(a,!0);var d=new Error("Cannot find module '"+a+"'");throw d.code="MODULE_NOT_FOUND",d}var p=r[a]={exports:{}};e[a][0].call(p.exports,function(t){var r=e[a][1][t];return n(r?r:t)},p,p.exports,t,e,r,o)}return r[a].exports}for(var i="function"==typeof require&&require,a=0;a").attr({type:"hidden",name:"project",value:t.project}).appendTo("#rtd-search-form"),$("").attr({type:"hidden",name:"version",value:t.version}).appendTo("#rtd-search-form"),$("").attr({type:"hidden",name:"type",value:"file"}).appendTo("#rtd-search-form"),$("#rtd-search-form").prop("action",t.api_host+"/elasticsearch/");var e=$("nav.wy-nav-side:first"),r=$(window),o="stickynav",i=function(){e.height()<=r.height()?e.addClass(o):e.removeClass(o)};r.on("resize",i),i()}}var n=t("./rtd-data");e.exports={init:o}},{"./rtd-data":4}],4:[function(t,e,r){function o(){var t=Object.create(n),e={api_host:"https://readthedocs.org"};return $.extend(t,e,window.READTHEDOCS_DATA),t}var n={is_rtd_theme:function(){return"sphinx_rtd_theme"===this.get_theme_name()},is_sphinx_builder:function(){return!("builder"in this)||"mkdocs"!=this.builder},get_theme_name:function(){return"sphinx_rtd_theme"!==this.theme&&1===$("div.rst-other-versions").length?"sphinx_rtd_theme":this.theme},show_promo:function(){return"https://readthedocs.com"!==this.api_host&&this.is_sphinx_builder()&&this.is_rtd_theme()}};e.exports={get:o}},{}],5:[function(t,e,r){function o(){function t(t){var e=t.closest("li");e.siblings("li.current").removeClass("current"),e.siblings().find("li.current").removeClass("current"),e.find("> ul li.current").removeClass("current"),e.toggleClass("current")}var e=n.get();$(document).on("click","[data-toggle='rst-current-version']",function(){var t=$("[data-toggle='rst-versions']").hasClass("shift-up")?"was_open":"was_closed";_gaq&&_gaq.push(["rtfd._setAccount","UA-17997319-1"],["rtfd._trackEvent","Flyout","Click",t])}),(!("builder"in e)||"builder"in e&&"mkdocs"!=e.builder)&&($(document).on("click","[data-toggle='wy-nav-top']",function(){$("[data-toggle='wy-nav-shift']").toggleClass("shift"),$("[data-toggle='rst-versions']").toggleClass("shift")}),$(document).on("click",".wy-menu-vertical .current ul li a",function(){var e=$(this);$("[data-toggle='wy-nav-shift']").removeClass("shift"),$("[data-toggle='rst-versions']").toggleClass("shift"),t(e),"undefined"!=typeof window.SphinxRtdTheme&&window.SphinxRtdTheme.StickyNav.hashChange()}),$(document).on("click","[data-toggle='rst-current-version']",function(){$("[data-toggle='rst-versions']").toggleClass("shift-up")}),$("table.docutils:not(.field-list)").wrap("
"),$(".wy-menu-vertical ul").siblings("a").each(function(){var e=$(this);expand=$(''),expand.on("click",function(r){return t(e),r.stopPropagation(),!1}),e.prepend(expand)}),window.SphinxRtdTheme=function(t){var e=function(){var e,r,o=!1,n=!1,i=0,a=function(){s(),c(),r.on("hashchange",c),r.on("scroll",function(){n||(o=!0)}),setInterval(function(){if(o){o=!1;var t=r.scrollTop(),n=e.scrollTop(),a=n+(t-i);e.scrollTop(a),i=t}},25)},s=function(){e=t("nav.wy-nav-side:first"),r=t(window)},c=function(){var t=encodeURI(window.location.hash);if(t)try{var e=$(".wy-menu-vertical").find('[href="'+t+'"]');$(".wy-menu-vertical li.toctree-l1 li.current").removeClass("current"),e.closest("li.toctree-l2").addClass("current"),e.closest("li.toctree-l3").addClass("current"),e.closest("li.toctree-l4").addClass("current")}catch(r){console.log("Error expanding nav for anchor",r)}},d=function(){n=!0,r.one("hashchange",function(){n=!1})};return t(s),{enable:a,hashChange:d}}();return{StickyNav:e}}($))}var n=t("./rtd-data");e.exports={init:o}},{"./rtd-data":4}],6:[function(t,e,r){function o(t){var e=n.get();if(!t.is_highest){var r=window.location.pathname.replace(e.version,t.slug),o=$('
');o.find("a").attr("href",r).text(t.version);var i=$("div.body");i.length||(i=$("div.document")),i.prepend(o)}}var n=t("./rtd-data");e.exports={init:o}},{"./rtd-data":4}],7:[function(t,e,r){var o=(t("./sponsorship"),t("./doc-embed/footer.js")),n=t("./doc-embed/grokthedocs-client"),i=t("./doc-embed/mkdocs"),a=(t("./doc-embed/rtd-data"),t("./doc-embed/sphinx"));$(document).ready(function(){o.init(),a.init(),n.init(),i.init()})},{"./doc-embed/footer.js":1,"./doc-embed/grokthedocs-client":2,"./doc-embed/mkdocs":3,"./doc-embed/rtd-data":4,"./doc-embed/sphinx":5,"./sponsorship":8}],8:[function(t,e,r){function o(t,e,r,o){this.id=t,this.text=e,this.link=r,this.image=o,this.promo=null}var n=window.$;e.exports={Promo:o},o.prototype.create=function(){function t(){_gaq&&_gaq.push(["rtfd._setAccount","UA-17997319-1"],["rtfd._trackEvent","Promo","Click",e.id])}var e=this,r=n("nav.wy-nav-side");if(r.length){promo=n("
").attr("class","wy-menu rst-pro");{var o=n("
").attr("class","rst-pro-about"),i=n("").attr("href","http://docs.readthedocs.org/en/latest/sponsors.html#sponsorship-information").appendTo(o);n("").attr("class","fa fa-info-circle").appendTo(i)}if(o.appendTo(promo),e.image){{var a=n("").attr("class","rst-pro-image-wrapper").attr("href",e.link).attr("target","_blank").on("click",t);n("").attr("class","rst-pro-image").attr("src",e.image).appendTo(a)}promo.append(a)}var s=n("").html(e.text);return n(s).find("a").each(function(){n(this).attr("class","rst-pro-link").attr("href",e.link).attr("target","_blank").on("click",t)}),promo.append(s),promo.appendTo(r),promo.wrapper=n("
").attr("class","rst-pro-wrapper").appendTo(r),promo}},o.prototype.display=function(){var t=this.promo;t||(t=this.promo=this.create()),t.show()},o.prototype.disable=function(){},o.from_variants=function(t){if(0==t.length)return null;var e=Math.floor(Math.random()*t.length),r=t[e],n=r.text,i=r.link,a=r.image,s=r.id;return new o(s,n,i,a)}},{}]},{},[7]); \ No newline at end of file