1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
{% extends "!layout.html" %}
{%- set current_version = "1.5.x circinus" %}
{% block extrahead %}
{% if gtm_id and cookiebot_id %}
{# Keep Cookiebot's consent dialog from rendering unstyled and breaking the page.
Cookiebot delivers its dialog CSS as a constructed stylesheet via
document.adoptedStyleSheets. That property holds the *whole* sheet list, and
ReadTheDocs' readthedocs-addons.js reassigns it with a destructive replace; when
that lands after Cookiebot's (network-gated) adoption it drops Cookiebot's sheet,
leaving #CybotCookiebotDialog at position:static, expanded to full page height.
This shim makes assignment preserve Cookiebot's sheet specifically. It must run
before the first adoptedStyleSheets write, so it is the first thing in <head>. #}
<script>
(function () {
try {
var desc = Object.getOwnPropertyDescriptor(Document.prototype, "adoptedStyleSheets");
if (!desc || !desc.get || !desc.set) return;
var guarded = null;
var isCookiebot = function (sheet) {
try {
var rules = sheet.cssRules;
for (var i = 0; i < rules.length; i++) {
if (rules[i].selectorText && rules[i].selectorText.indexOf("CybotCookiebotDialog") !== -1) return true;
}
} catch (e) {}
return false;
};
Object.defineProperty(document, "adoptedStyleSheets", {
configurable: true,
get: function () { return desc.get.call(document); },
set: function (sheets) {
for (var i = 0; i < sheets.length; i++) {
if (isCookiebot(sheets[i])) { guarded = sheets[i]; break; }
}
if (guarded && Array.prototype.indexOf.call(sheets, guarded) === -1) {
sheets = Array.prototype.slice.call(sheets).concat(guarded);
}
desc.set.call(document, sheets);
}
});
} catch (e) {}
})();
</script>
{# Cookiebot CMP — must load first so its auto-blocker can scan/block other tags #}
<script id="Cookiebot"
src="https://consent.cookiebot.com/uc.js"
data-cbid="{{ cookiebot_id }}"
data-blockingmode="auto"
type="text/javascript"></script>
{# Google Consent Mode v2 defaults — deny everything until Cookiebot fires the update #}
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){window.dataLayer.push(arguments);}
gtag('consent', 'default', {
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'analytics_storage': 'denied',
'functionality_storage': 'denied',
'personalization_storage': 'denied',
'security_storage': 'granted',
'wait_for_update': 500
});
gtag('set', 'ads_data_redaction', true);
</script>
{# Google Tag Manager #}
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','{{ gtm_id }}');</script>
{% endif %}
<style>#vyos-header-iframe{position:fixed;top:0;left:0;right:0;z-index:999999999;width:100%;border:none}</style>
<style>#vyos-footer-iframe{width:100%;border:none}</style>
<iframe src='https://vyos.io/iframes/header' id='vyos-header-iframe'></iframe>
<script>const iframeHeader=document.getElementById('vyos-header-iframe');const postMessageToIframe=()=>{iframeHeader.contentWindow.postMessage({height:window.innerHeight,width:window.width},'*')};window.addEventListener('message',function(message){if(message.data.headerIframeHeight){iframeHeader.style.height=`${message.data.headerIframeHeight}px`;postMessageToIframe()}});window.addEventListener('resize',event=>{postMessageToIframe()})</script>
<link href="{{ pathto("_static/css/custom.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/lists.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/hints.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/headers.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/breadcrumbs.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/linkButtons.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/text.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/leftSidebar.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/scrolls.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/tables.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/installation/running-on-bare-metal.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/code-snippets.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/separate-commands.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/configuration/index.css", True) }}" rel="stylesheet" type="text/css">
<link href="{{ pathto("_static/css/datatables.css", True) }}" rel="stylesheet" type="text/css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/datatables.js", True) }}"></script>
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/tables.js", True) }}"></script>
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/codecopier.js", True) }}"></script>
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/sidebar.js", True) }}"></script>
<script type="text/javascript" charset="utf8" src="{{ pathto("_static/js/footer.js", True) }}"></script>
{% endblock %}
{% block body %}
{% if gtm_id and cookiebot_id %}
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ gtm_id }}"
height="0" width="0" style="display:none;visibility:hidden"
title="Google Tag Manager"></iframe></noscript>
{% endif %}
{{ super() }}
{% endblock %}
|