diff --git a/media/css/readthedocs-doc-embed.css b/media/css/readthedocs-doc-embed.css index ac46963eb8d..26cc8e0a8a3 100644 --- a/media/css/readthedocs-doc-embed.css +++ b/media/css/readthedocs-doc-embed.css @@ -42,144 +42,77 @@ To support sphinx_rtd_theme, a `wy-menu` element is added. Other themes are targeted using the theme identifier and use custom elements instead of a CSS framework html structure. -div.rst-pro is deprecated in favor of div.rtd-pro here, though we still need -both rules for historical docs. */ -div.rtd-pro, -div.rst-pro { - display: block; - padding: .5em; - margin: 1em 0em 1em 0em; - text-align: center; +div.ethical-sidebar, div.ethical-footer { + display: block !important; } -div.rtd-pro.wy-menu, -div.rtd-pro.wy-menu { - width: 300px; -} -div.rtd-pro.alabaster { - width: 100%; - box-sizing: border-box; -} - -div.rtd-pro.wy-menu, -div.rst-pro.wy-menu { - bottom: 60px; - background: rgba(0, 0, 0, .06); -} - -div.rtd-pro.alabaster { - background: rgba(220, 220, 220, .1); -} - -div.rtd-pro > span, -div.rst-pro > span { - display: block; - font-size: 90%; -} - -div.rtd-pro.wy-menu > span, -div.rst-pro.wy-menu > span { - color: #b3b3b3; -} - -div.rtd-pro.wy-menu a, -div.rtd-pro.wy-menu a:link, -div.rtd-pro.wy-menu a:visited, -div.rst-pro.wy-menu a, -div.rst-pro.wy-menu a:link, -div.rst-pro.wy-menu a:visited, -div.rtd-pro.wy-menu a:hover, -div.rtd-pro.wy-menu a:active, -div.rst-pro.wy-menu a:hover, -div.rst-pro.wy-menu a:active { color: #efefef; } - -div.rtd-pro a.rtd-pro-image-wrapper { - display: inline-block; - padding: 6px; - margin: 5px 0px 10px 0px; - border: 1px solid #434343; - border-radius: 3px; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; -} - -div.rtd-pro.wy-menu a.rtd-pro-image-wrapper, -div.rst-pro.wy-menu a.rst-pro-image-wrapper { - border-color: #434343; -} - -div.rtd-pro.alabaster a.rtd-pro-image-wrapper { - border-color: #d3d3d3; +.ethical-sidebar, .ethical-footer { + padding: .5em; + margin: 1em 0; } - -div.rtd-pro img, -div.rst-pro.wy-menu img { +.ethical-sidebar img, .ethical-footer img { width: 120px; height: 90px; + display: inline-block; } - -div.rtd-pro div.rtd-pro-about { - float: right; - text-align: right; - font-size: 90%; +.ethical-sidebar .ethical-callout, .ethical-footer .ethical-callout { + padding-top: 1em; + clear: both; } -div.rtd-pro.wy-menu div.rtd-pro-about, -div.rst-pro.wy-menu div.rst-pro-about { - color: white; +.ethical-sidebar .ethical-pixel, .ethical-footer .ethical-pixel { + display: none !important; } - -div.rtd-pro.alabaster div.rtd-pro-about a { - border-bottom: 0px; +.ethical-sidebar .ethical-text, .ethical-footer .ethical-text { + margin-top: 1em; } - -div.rtd-pro.alabaster div.rtd-pro-about i.fa-info-circle:before, -div.rtd-pro.rtd-pro-footer div.rtd-pro-about i.fa-info-circle:before { - content: ""; - color: #a3a3a3; +.ethical-sidebar .ethical-image-link, .ethical-footer .ethical-image-link { + border: 0; } -/* Hide the "sponsored" note in the left navigation */ -div.rtd-pro-about span { - display: none; +/* Sidebar promotions */ +.ethical-sidebar { + text-align: center; } -/* Footer promos */ -div.rtd-pro.rtd-pro-footer div.rtd-pro-about span { - display: inline; -} -div.rtd-pro.rtd-pro-footer div.rtd-pro-about { - float: none; -} -div.rtd-pro.rtd-pro-footer div.rtd-pro-about a { - text-decoration: none; -} -div.rtd-pro.rtd-pro-footer { +/* Footer promotions */ +.ethical-footer { text-align: left; + font-size: 90%; } -div.rtd-pro.rtd-pro-footer a.rtd-pro-image-wrapper { +.ethical-footer img { float: right; margin-left: 25px; } - -div.rtd-pro-wrapper { - clear: both; +.ethical-footer .ethical-callout { + text-align: right; } -@media (max-width: 768px) { - div.rst-pro.wy-menu { - display: none; - } +/* RTD Theme specific customizations */ +.ethical-rtd .ethical-sidebar { + /* RTD theme doesn't set sidebar text color */ + color: #b3b3b3; - div.rtd-pro.alabaster { - background: rgba(220, 220, 220, .05); - } + /* RTD theme doesn't correctly set the sidebar width */ + width: 300px; - div.rtd-pro.alabaster a.rtd-pro-image-wrapper { - border-color: #656565; - } + font-size: 14px; + line-height: 20px; +} +.ethical-rtd .ethical-sidebar a, +.ethical-rtd .ethical-sidebar a:visited, +.ethical-rtd .ethical-sidebar a:hover, +.ethical-rtd .ethical-sidebar a:active { + /* RTD theme doesn't set sidebar link color */ + color: #efefef; } -div.rtd-pro > p.ethical-callout { - margin-top: 1em; +/* Alabaster specific customizations */ +.ethical-alabaster a.ethical-image-link { + /* Alabaster adds a border even to image links on hover */ + border: 0 !important; +} +.ethical-alabaster hr { + /* Alabaster needs some extra spacing before the footer ad */ + margin-top: 2em; } diff --git a/readthedocs/core/static-src/core/js/doc-embed/constants.js b/readthedocs/core/static-src/core/js/doc-embed/constants.js index 13fc45ba6cc..5474def9285 100644 --- a/readthedocs/core/static-src/core/js/doc-embed/constants.js +++ b/readthedocs/core/static-src/core/js/doc-embed/constants.js @@ -3,18 +3,18 @@ var exports = { THEME_RTD: 'sphinx_rtd_theme', THEME_ALABASTER: 'alabaster', - THEME_CELERY: 'sphinx_celery' -} + THEME_CELERY: 'sphinx_celery', +}; exports.PROMO_SUPPORTED_THEMES = [ exports.THEME_RTD, exports.THEME_ALABASTER, - exports.THEME_CELERY -] + exports.THEME_CELERY, +]; exports.PROMO_TYPES = { LEFTNAV: 'doc', // Left navigation on documentation pages - FOOTER: 'site-footer' // Footer of documentation pages + FOOTER: 'site-footer', // Footer of documentation pages }; module.exports = exports; 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 aa957bd1439..3cca7456697 100644 --- a/readthedocs/core/static-src/core/js/doc-embed/footer.js +++ b/readthedocs/core/static-src/core/js/doc-embed/footer.js @@ -1,6 +1,5 @@ var rtddata = require('./rtd-data'); var versionCompare = require('./version-compare'); -var sponsorship = require('../sponsorship'); function injectFooter(data) { @@ -19,22 +18,6 @@ function injectFooter(data) { } else if (!data['version_supported']) { //$('.rst-current-version').addClass('rst-active-old-version') } - - // Show promo selectively - if (data.promo && config.show_promo()) { - var promo = new sponsorship.Promo( - data.promo_data.id, - data.promo_data.text, - data.promo_data.link, - data.promo_data.image, - config.theme, - data.promo_data.display_type, - data.promo_data.pixel - ) - if (promo) { - promo.display(); - } - } } @@ -53,7 +36,6 @@ function setupBookmarkCSRFToken() { }); } - function init() { var rtd = rtddata.get(); @@ -79,15 +61,6 @@ function init() { get_data['subproject'] = true; } - if (typeof URL !== 'undefined' && typeof URLSearchParams !== 'undefined') { - // Force a specific promo to be displayed - var params = new URL(window.location).searchParams; - var force_promo = params.get('promo'); - if (force_promo) { - get_data['promo'] = force_promo; - } - } - // Get footer HTML from API and inject it into the page. $.ajax({ url: rtd.api_host + "/api/v2/footer_html/", @@ -108,7 +81,6 @@ function init() { }); } - module.exports = { init: init }; diff --git a/readthedocs/core/static-src/core/js/doc-embed/sponsorship.js b/readthedocs/core/static-src/core/js/doc-embed/sponsorship.js new file mode 100644 index 00000000000..e1257c1dc28 --- /dev/null +++ b/readthedocs/core/static-src/core/js/doc-embed/sponsorship.js @@ -0,0 +1,182 @@ +/* Read the Docs - Documentation promotions */ + +var constants = require('./constants'); +var rtddata = require('./rtd-data'); + +var rtd; + +/* + * Creates a sidebar div where an ad could go + */ +function create_sidebar_placement () { + var element_id = 'rtd-' + (Math.random() + 1).toString(36).substring(4); + var display_type = constants.PROMO_TYPES.LEFTNAV; + var selector = null; + var class_name; // Used for theme specific CSS customizations + + if (rtd.is_rtd_theme()) { + selector = 'nav.wy-nav-side > div.wy-side-scroll'; + class_name = 'ethical-rtd'; + } else if (rtd.get_theme_name() === constants.THEME_ALABASTER || + rtd.get_theme_name() === constants.THEME_CELERY) { + selector = 'div.sphinxsidebar > div.sphinxsidebarwrapper'; + class_name = 'ethical-alabaster'; + } + + if (selector) { + $('
').attr('id', element_id) + .addClass(class_name).appendTo(selector); + return {'div_id': element_id, 'display_type': display_type}; + } + + return null; +} + +/* + * Creates a sidebar div where an ad could go + * Returns the ID of the div or none if no footer ad is possible + */ +function create_footer_placement () { + var element_id = 'rtd-' + (Math.random() + 1).toString(36).substring(4); + var display_type = constants.PROMO_TYPES.FOOTER; + var selector = null; + var class_name; + + if (rtd.is_rtd_theme()) { + selector = $('').insertAfter('footer hr'); + class_name = 'ethical-rtd'; + } else if (rtd.get_theme_name() === constants.THEME_ALABASTER || + rtd.get_theme_name() === constants.THEME_CELERY) { + selector = 'div.bodywrapper .body'; + class_name = 'ethical-alabaster'; + } + + if (selector) { + $('').attr('id', element_id) + .addClass(class_name).appendTo(selector); + return {'div_id': element_id, 'display_type': display_type}; + } + + return null; +} + +/* + * Returns an array of possible places where a promo could go + */ +function get_placements () { + var placements = []; + var placement_funcs = [create_footer_placement, create_sidebar_placement]; + var placement; + + for (var i = 0; i < placement_funcs.length; i += 1) { + placement = placement_funcs[i](); + if (placement) { + placements.push(placement); + } + } + + return placements; +} + +function Promo (data) { + this.id = data.id; // analytics id + this.div_id = data.div_id || ''; + this.html = data.html || ''; + this.display_type = data.display_type || ''; + + // Handler when a promo receives a click + this.click_handler = function () { + // This needs to handle both old style legacy analytics for previously built docs + // as well as the newer universal analytics + if (typeof ga !== 'undefined') { + ga('rtfd.send', 'event', 'Promo', 'Click', data.id); + } else if (typeof _gaq !== 'undefined') { + _gaq.push( + ['rtfd._setAccount', 'UA-17997319-1'], + ['rtfd._trackEvent', 'Promo', 'Click', data.id] + ); + } + }; +} + +/* + * Position and inject the promo + */ +Promo.prototype.display = function () { + $('#' + this.div_id).html(this.html); + $('#' + this.div_id).find('a[href*="/sustainability/click/"]') + .on('click', this.click_handler); + + this.post_promo_display(); +}; + +Promo.prototype.disable = function () { + $('#' + this.div_id).hide(); +}; + +/* + * Perform any additional tweaks after the ad is successfully injected + */ +Promo.prototype.post_promo_display = function () { + if (this.display_type === constants.PROMO_TYPES.FOOTER) { + $('' + - 'Ads served ethically' + - '
' - ) - promo.append(copy_text); - - - promo.appendTo(selector); - - promo.wrapper = $('') - .attr('class', 'rtd-pro-wrapper') - .appendTo(selector); - - return promo; -}; - -Promo.prototype.get_alabaster_promo_selector = function () { - // Return a jQuery selector where the promo goes on the Alabaster theme - var self = this; - var selector; - var wrapper; - - if (self.display_type === constants.PROMO_TYPES.FOOTER) { - wrapper = $('') - .attr('class', 'rtd-pro-footer-wrapper body') - .appendTo('div.bodywrapper'); - $('