Skip to content

Commit

Permalink
code clipboard feature
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianogtl committed Jun 12, 2024
1 parent 1728482 commit cb72e93
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 111 deletions.
21 changes: 20 additions & 1 deletion css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ pre {
font-family: var(--font-mono);
color: var(--dark-gray-color);
background-color: var(--light-gray-color);
overflow-x: scroll;
white-space: pre-wrap;
overflow-x: hidden;
}

code {
Expand All @@ -158,6 +159,24 @@ pre {
white-space: pre-line;
}

.container-code {
position: relative;
}

.clipboard-btn {
position: absolute;
right: 0.5rem;
bottom: 0.5rem;
padding: 0.3rem;
font-family: var(--font-sans);
font-size: 1rem;
border: none;
}

.clipboard-btn:hover {
cursor: pointer;
}

.external-link:after {
font-family: "Material Symbols Rounded";
content: "open_in_new";
Expand Down
194 changes: 108 additions & 86 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,14 @@ <h2>Hello world</h2>
To get started with writing JavaScript, open the Scratchpad and
write your first "Hello world" JavaScript code:
</p>
<pre class="code-exemple">
function greetMe(yourName) {
&nbsp;alert("Hello " + yourName);
}
greetMe("World");
</pre>
<div class="container-code">
<pre class="code-exemple">
function greetMe(yourName) {
&nbsp;alert("Hello " + yourName);
}
greetMe("World");
</pre>
</div>
<p>
Select the code in the pad and hit Ctrl+R to watch it unfold in
your browser!
Expand Down Expand Up @@ -255,23 +257,26 @@ <h2>Variable scope</h2>
the function (or global context) within which x is declared, not
the block, which in this case is an if statement.
</p>
<pre class="code-exemple">
if (true) {
&nbsp;var x = 5;
}
console.log(x); // 5
</pre
>
<div class="container-code">
<pre class="code-exemple">
if (true) {
&nbsp;var x = 5;
}
console.log(x); // 5
</pre>
</div>
<p>
This behavior changes, when using the let declaration introduced
in ECMAScript 2015.
</p>
<pre class="code-exemple">
if (true) {
let y = 5;
}
console.log(y); // ReferenceError: y is not defined
</pre>
<div class="container-code">
<pre class="code-exemple">
if (true) {
let y = 5;
}
console.log(y); // ReferenceError: y is not defined
</pre>
</div>
</article>
</section>
<section id="global-variables" class="section">
Expand Down Expand Up @@ -316,26 +321,30 @@ <h2>Constants</h2>
You cannot declare a constant with the same name as a function or
variable in the same scope. For example:
</p>
<pre class="code-exemple">
// THIS WILL CAUSE AN ERROR
function f() {};
&nbsp;const f = 5; // THIS WILL CAUSE AN ERROR ALSO
function f() {
&nbsp;const g = 5;
&nbsp;var g;
&nbsp;//statements
}
</pre>
<div class="container-code">
<pre class="code-exemple">
// THIS WILL CAUSE AN ERROR
function f() {};
&nbsp;const f = 5; // THIS WILL CAUSE AN ERROR ALSO
function f() {
&nbsp;const g = 5;
&nbsp;var g;
&nbsp;//statements
}
</pre>
</div>
<p>
However, object attributes are not protected, so the following
statement is executed without problems.
</p>
<pre class="code-exemple">
const MY_OBJECT = {
&nbsp;"key": "value"
};
MY_OBJECT.key = "otherValue";
</pre>
<div class="container-code">
<pre class="code-exemple">
const MY_OBJECT = {
&nbsp;"key": "value"
};
MY_OBJECT.key = "otherValue";
</pre>
</div>
</article>
</section>
<section id="data-types" class="section">
Expand Down Expand Up @@ -380,13 +389,15 @@ <h2>if else statement</h2>
is true. Use the optional else clause to execute a statement if
the condition is false. An if statement looks as follows:
</p>
<pre class="code-exemple">
if (condition) {
&nbsp;statement_1;
} else {
&nbsp;statement_2;
}
</pre>
<div class="container-code">
<pre class="code-exemple">
if (condition) {
&nbsp;statement_1;
} else {
&nbsp;statement_2;
}
</pre>
</div>
<p>
condition can be any expression that evaluates to true or false.
See Boolean for an explanation of what evaluates to true and
Expand All @@ -398,55 +409,62 @@ <h2>if else statement</h2>
You may also compound the statements using else if to have
multiple conditions tested in sequence, as follows:
</p>
<pre class="code-exemple">
if (condition_1) {
&nbsp;statement_1;
} else if (condition_2) {
&nbsp;statement_2;
} else if (condition_n) {
&nbsp;statement_n;
} else {
&nbsp;statement_last;
}
</pre>
<div class="container-code">
<pre class="code-exemple">
if (condition_1) {
&nbsp;statement_1;
} else if (condition_2) {
&nbsp;statement_2;
} else if (condition_n) {
&nbsp;statement_n;
} else {
&nbsp;statement_last;
}
</pre>
</div>
<p>
In the case of multiple conditions only the first logical
condition which evaluates to true will be executed. To execute
multiple statements, group them within a block statement
<code>{ ... }</code> . In general, it's good practice to always
use block statements, especially when nesting if statements:
</p>
<pre class="code-exemple">
if (condition) {
&nbsp;statement_1_runs_if_condition_is_true;
&nbsp;statement_2_runs_if_condition_is_true;
}&nbsp;else {
&nbsp;statement_3_runs_if_condition_is_false;
&nbsp;statement_4_runs_if_condition_is_false;
}
</pre
>
<div class="container-code">
<pre class="code-exemple">
if (condition) {
&nbsp;statement_1_runs_if_condition_is_true;
&nbsp;statement_2_runs_if_condition_is_true;
}&nbsp;else {
&nbsp;statement_3_runs_if_condition_is_false;
&nbsp;statement_4_runs_if_condition_is_false;
}
</pre>
</div>
<p>
It is advisable to not use simple assignments in a conditional
expression, because the assignment can be confused with equality
when glancing over the code. For example, do not use the following
code:
</p>
<pre class="code-exemple">
if (x = y) {
&nbsp;/* statements here */
}
</pre>
<div class="container-code">
<pre class="code-exemple">
if (x = y) {
&nbsp;/* statements here */
}
</pre>
</div>
<p>
If you need to use an assignment in a conditional expression, a
common practice is to put additional parentheses around the
assignment. For example:
</p>
<pre class="code-exemple">
if ((x = y)) {
&nbsp;/* statements here */
}
</pre>
<div class="container-code">
<pre class="code-exemple">
if ((x = y)) {
&nbsp;/* statements here */
}
</pre>
</div>
</article>
</section>
<section id="while-statement" class="section">
Expand Down Expand Up @@ -475,14 +493,16 @@ <h2>while statement</h2>
<p>
The following while loop iterates as long as n is less than three:
</p>
<pre class="code-exemple">
var n = 0;
var x = 0;
while (n < 3) {
&nbsp;n++;
&nbsp;x += n;
}
</pre>
<div class="container-code">
<pre class="code-exemple">
var n = 0;
var x = 0;
while (n < 3) {
&nbsp;n++;
&nbsp;x += n;
}
</pre>
</div>
<p>
With each iteration, the loop increments n and adds that value to
<code>x</code>. Therefore, <code>x</code> and <code>n</code> take
Expand Down Expand Up @@ -527,11 +547,13 @@ <h2>Function declarations</h2>
For example, the following code defines a simple function named
square:
</p>
<pre class="code-exemple">
function square(number) {
&nbsp;return number * number;
}
</pre>
<div class="container-code">
<pre class="code-exemple">
function square(number) {
&nbsp;return number * number;
}
</pre>
</div>
<p>
The function square takes one argument, called number. The
function consists of one statement that says to return the
Expand Down
75 changes: 51 additions & 24 deletions script.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
const nav = document.querySelector("nav");
const docTitle = document.querySelector("#doc-title");
const scrollToTopBtn = document.querySelector("#scroll-to-top-btn");
const scrollToTopContainer = document.querySelector(".scroll-to-top-container");

const isPhoneOrTouch =
/Android|iPhone/i.test(navigator.userAgent) || navigator.maxTouchPoints > 0;

function animateLogo() {
const nav = document.querySelector("nav");
const docTitle = document.querySelector("#doc-title");
nav.onmouseenter = (e) => docTitle.classList.add("nav-hover");
nav.onmouseout = (e) => {
const mouseOutNav = !nav.contains(e.relatedTarget);
Expand All @@ -16,30 +10,63 @@ function animateLogo() {
};
}

function fixBackToTopBtn() {
function fixBackToTopBtn(scrollToTopBtn, scrollToTopContainer) {
scrollToTopContainer.style.position = "absolute";
scrollToTopBtn.style.display = "none";
scrollToTopBtn.style.position = "fixed";
scrollToTopBtn.style.right = "unset";
}

scrollToTopBtn.addEventListener("click", () => {
window.scrollTo({
top: 0,
behavior: "smooth",
function addClipboardBtns() {
const containerCodeArr = Array.from(
document.querySelectorAll(".container-code")
);

containerCodeArr.forEach((containerCode) => {
containerCode.innerHTML += `<button class="clipboard-btn" title="Copy to clipboard">Copy</button>`;

const clipboardBtn = containerCode.children[1];
const preTagContent = containerCode.children[0].textContent;
addClipboardEvent(clipboardBtn, preTagContent);
});
}

function addClipboardEvent(clipboardBtn, preTagContent) {
clipboardBtn.onclick = () => {
navigator.clipboard.writeText(preTagContent);
};
}

function addScrollEvents(scrollToTopBtn) {
scrollToTopBtn.addEventListener("click", () => {
window.scrollTo({
top: 0,
behavior: "smooth",
});
});

window.addEventListener("scroll", () => {
if (window.scrollY > 800) {
scrollToTopBtn.style.display = "block";
} else {
scrollToTopBtn.style.display = "none";
}
});
});
}

window.addEventListener("scroll", () => {
if (window.scrollY > 800) {
scrollToTopBtn.style.display = "block";
function main() {
const deviceHasTouchScreen = navigator.maxTouchPoints > 0;
const scrollToTopBtn = document.querySelector("#scroll-to-top-btn");
const scrollToTopContainer = document.querySelector(
".scroll-to-top-container"
);

addScrollEvents(scrollToTopBtn);
if (deviceHasTouchScreen) {
fixBackToTopBtn(scrollToTopBtn, scrollToTopContainer);
} else {
scrollToTopBtn.style.display = "none";
animateLogo();
addClipboardBtns();
}
});

if (isPhoneOrTouch) {
fixBackToTopBtn();
} else {
animateLogo();
}
main();

0 comments on commit cb72e93

Please sign in to comment.