Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
keras-team
GitHub Repository: keras-team/keras-io
Path: blob/master/theme/js/index.js
8042 views
1
// Mobile nav controls
2
const navButton = document.querySelector('.nav__menu--button');
3
const closeButton = document.querySelector('.nav__menu--close');
4
const mobileNavMenu = document.querySelector('.k-nav');
5
const pageContainer = document.querySelector('.page__container');
6
7
navButton.addEventListener('click', () => {
8
mobileNavMenu.style.display = 'block';
9
closeButton.style.display = 'block';
10
navButton.style.display = 'none';
11
pageContainer.style.position = 'fixed';
12
});
13
14
closeButton.addEventListener('click', () => {
15
mobileNavMenu.style.display = 'none';
16
closeButton.style.display = 'none';
17
navButton.style.display = 'block';
18
pageContainer.style.position = 'static';
19
});
20
21
// Copy code
22
function addCopyButtonsToCodeBlocks() {
23
// Find all code blocks with .codehilite class, excluding those inside .k-default-codeblock
24
const allCodeBlocks = document.querySelectorAll('.codehilite:not(.k-default-codeblock .codehilite)');
25
26
allCodeBlocks.forEach((block) => {
27
// Skip if button already exists
28
if (block.querySelector('.code__copy--button')) {
29
return;
30
}
31
32
// Create copy button
33
const button = document.createElement('button');
34
button.className = 'code__copy--button';
35
button.setAttribute('aria-label', 'Copy code to clipboard');
36
37
// Create icon element
38
const icon = document.createElement('i');
39
icon.className = 'icon--copy';
40
button.appendChild(icon);
41
42
// Create tooltip
43
const tooltip = document.createElement('div');
44
tooltip.className = 'code__copy--tooltip';
45
tooltip.textContent = 'Copied!';
46
button.appendChild(tooltip);
47
48
// Add button to container
49
block.insertBefore(button, block.firstChild);
50
51
// Add click event listener
52
button.addEventListener('click', () => {
53
// Find the code element
54
const codeElement = block.querySelector('pre code') || block.querySelector('code') || block.querySelector('pre');
55
if (!codeElement) return;
56
57
let text = codeElement.innerText || codeElement.textContent;
58
59
// Clean the text: remove Python prompts and continuation markers
60
text = cleanCodeText(text);
61
62
// Copy to clipboard using fallback method for better reliability
63
copyWithFallback(text, button);
64
});
65
});
66
}
67
68
function cleanCodeText(text) {
69
// Remove Python interactive prompt characters (>>>, ...)
70
// Split by lines, process each line, then rejoin
71
const lines = text.split('\n');
72
const cleanedLines = lines.map(line => {
73
// Remove >>> at the start of line (with optional spaces)
74
line = line.replace(/^\s*>>>\s?/, '');
75
// Remove ... at the start of line (with optional spaces) - continuation prompt
76
line = line.replace(/^\s*\.\.\.\s?/, '');
77
return line;
78
});
79
80
return cleanedLines.join('\n');
81
}
82
83
function copyWithFallback(text, button) {
84
const inputElement = document.createElement('textarea');
85
inputElement.value = text;
86
inputElement.setAttribute('readonly', '');
87
inputElement.style.position = 'absolute';
88
inputElement.style.left = '-9999px';
89
document.body.appendChild(inputElement);
90
inputElement.select();
91
92
try {
93
document.execCommand('copy');
94
showCopyTooltip(button);
95
} catch (err) {
96
console.error('Failed to copy text:', err);
97
}
98
99
inputElement.remove();
100
}
101
102
function showCopyTooltip(button) {
103
const tooltip = button.querySelector('.code__copy--tooltip');
104
if (tooltip) {
105
tooltip.style.display = 'block';
106
setTimeout(() => {
107
tooltip.style.display = 'none';
108
}, 2000);
109
}
110
}
111
112
// Add copy buttons on page load
113
document.addEventListener('DOMContentLoaded', addCopyButtonsToCodeBlocks);
114
115
// Existing copy buttons (for landing page compatibility)
116
const copyButtons = document.querySelectorAll('.code__copy--button');
117
copyButtons.forEach((button) => {
118
button.addEventListener('click', () => {
119
const parent = button.parentNode;
120
const text = parent.querySelector('.language-python').innerText;
121
const inputElement = document.createElement('textarea');
122
console.log('text', text);
123
inputElement.value = text;
124
inputElement.setAttribute('class', 'visually-hidden');
125
const body = document.body;
126
body.appendChild(inputElement);
127
inputElement.select();
128
document.execCommand('copy');
129
inputElement.remove();
130
131
button.querySelector('.code__copy--tooltip').style.display = 'block';
132
setTimeout(() => {
133
button.querySelector('.code__copy--tooltip').style.display = 'none';
134
}, 2000);
135
});
136
});
137
138
// Search controls
139
const searchForms = document.querySelectorAll('.nav__search');
140
const mobileNavSearchIcon = document.querySelector('.nav__search--mobile');
141
const mobileNavSearchForm = document.querySelector('.nav__search-form--mobile');
142
const mobileNavControls = document.querySelector('.nav__controls--mobile');
143
const desktopSearch = document.querySelector('.nav__menu .nav__search');
144
145
mobileNavSearchIcon.addEventListener('click', () => {
146
mobileNavControls.style.display = 'none';
147
mobileNavSearchForm.style.display = 'block';
148
});
149
150
searchForms.forEach((search) => {
151
search.addEventListener('submit', (event) => {
152
event.preventDefault();
153
const text = search.querySelector('.nav__search--input').value;
154
window.location = `/search.html?query=${text}`;
155
});
156
});
157
158
pageContainer.addEventListener('click', () => {
159
mobileNavControls.style.display = 'flex';
160
mobileNavSearchForm.style.display = 'none';
161
});
162
163
mobileNavMenu.addEventListener('click', () => {
164
mobileNavControls.style.display = 'flex';
165
mobileNavSearchForm.style.display = 'none';
166
});
167
168
if (window.location.pathname.indexOf('search.html') > -1) {
169
desktopSearch.style.display = 'none';
170
mobileNavSearchIcon.style.visibility = 'hidden';
171
}
172
173
// position:sticky functionality (set margin-top so that the content is correctly centered vertically)
174
const exploreModule = document.querySelector('.explore');
175
const exploreContent = document.querySelector('.explore__content');
176
177
const observer = new IntersectionObserver(
178
(entries) => {
179
entries.forEach((entry) => {
180
if (entry.isIntersecting) {
181
window.addEventListener('resize', verticallyCenterExploreContent);
182
return;
183
}
184
185
window.removeEventListener('resize', verticallyCenterExploreContent);
186
});
187
},
188
{ threshold: 0 }
189
);
190
191
if (exploreModule && window.innerWidth > 1199) {
192
observer.observe(exploreModule);
193
/* let's call it once initially to align it in case a screen never gets resized */
194
verticallyCenterExploreContent();
195
}
196
197
function verticallyCenterExploreContent() {
198
exploreContent.style.marginTop = `${Math.round(exploreContent.getBoundingClientRect().height / 2)}px`;
199
}
200
201