From dd3f629d732e68069fdbc038bdb73c645be309fb Mon Sep 17 00:00:00 2001
From: Tom <20648924+moT01@users.noreply.github.com>
Date: Mon, 23 Sep 2024 01:48:28 -0500
Subject: [PATCH] feat(curriculum): add technical documentation page lab
(#56154)
Co-authored-by: Dario-DC <105294544+Dario-DC@users.noreply.github.com>
---
client/i18n/locales/english/intro.json | 7 +-
.../lab-technical-documentation-page/index.md | 9 +
.../meta.json | 16 +
.../587d78b0367417b2b2512b05.md | 847 ++++++++++++++++++
4 files changed, 878 insertions(+), 1 deletion(-)
create mode 100644 client/src/pages/learn/front-end-development/lab-technical-documentation-page/index.md
create mode 100644 curriculum/challenges/_meta/lab-technical-documentation-page/meta.json
create mode 100644 curriculum/challenges/english/25-front-end-development/lab-technical-documentation-page/587d78b0367417b2b2512b05.md
diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json
index a132c3a10dc..8c08fbe6d4d 100644
--- a/client/i18n/locales/english/intro.json
+++ b/client/i18n/locales/english/intro.json
@@ -1875,7 +1875,12 @@
"rbnd": { "title": "102", "intro": [] },
"xebj": { "title": "103", "intro": [] },
"jkdt": { "title": "104", "intro": [] },
- "cbbz": { "title": "105", "intro": [] },
+ "lab-technical-documentation-page": {
+ "title": "Build a Technical Documentation Page",
+ "intro": [
+ "For this lab, you will build a technical documentation page to serve as instruction or reference for a topic."
+ ]
+ },
"xcti": { "title": "106", "intro": [] },
"scec": { "title": "107", "intro": [] },
"mtbl": { "title": "108", "intro": [] },
diff --git a/client/src/pages/learn/front-end-development/lab-technical-documentation-page/index.md b/client/src/pages/learn/front-end-development/lab-technical-documentation-page/index.md
new file mode 100644
index 00000000000..8fdd13968d7
--- /dev/null
+++ b/client/src/pages/learn/front-end-development/lab-technical-documentation-page/index.md
@@ -0,0 +1,9 @@
+---
+title: Introduction to the Technical Documentation Page
+block: lab-technical-documentation-page
+superBlock: front-end-development
+---
+
+## Introduction to the Technical Documentation Page
+
+For this project, you will build a technical documentation page to serve as instruction or reference for a topic.
diff --git a/curriculum/challenges/_meta/lab-technical-documentation-page/meta.json b/curriculum/challenges/_meta/lab-technical-documentation-page/meta.json
new file mode 100644
index 00000000000..d7e19a22482
--- /dev/null
+++ b/curriculum/challenges/_meta/lab-technical-documentation-page/meta.json
@@ -0,0 +1,16 @@
+{
+ "name": "Build a Technical Documentation Page",
+ "blockType": "lab",
+ "isUpcomingChange": true,
+ "usesMultifileEditor": true,
+ "dashedName": "lab-technical-documentation-page",
+ "order": 105,
+ "superBlock": "front-end-development",
+ "challengeOrder": [
+ {
+ "id": "587d78b0367417b2b2512b05",
+ "title": "Build a Technical Documentation Page"
+ }
+ ],
+ "helpCategory": "HTML-CSS"
+}
diff --git a/curriculum/challenges/english/25-front-end-development/lab-technical-documentation-page/587d78b0367417b2b2512b05.md b/curriculum/challenges/english/25-front-end-development/lab-technical-documentation-page/587d78b0367417b2b2512b05.md
new file mode 100644
index 00000000000..2d2fda2a00d
--- /dev/null
+++ b/curriculum/challenges/english/25-front-end-development/lab-technical-documentation-page/587d78b0367417b2b2512b05.md
@@ -0,0 +1,847 @@
+---
+id: 587d78b0367417b2b2512b05
+title: Build a Technical Documentation Page
+challengeType: 14
+demoType: onClick
+dashedName: build-a-technical-documentation-page
+---
+
+# --description--
+
+**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.
+
+**User Stories:**
+
+1. You can see a `main` element with a corresponding `id="main-doc"`, which contains the page's main content (technical documentation).
+1. Within the `#main-doc` element, you can see several `section` elements, each with a class of `main-section`. There should be a minimum of five.
+1. The first element within each `.main-section` should be a `header` element, which contains text that describes the topic of that section.
+1. Each `section` element with the class of `main-section` should also have an `id` that corresponds with the text of each `header` contained within it. Any spaces should be replaced with underscores (e.g. The section that contains the header "JavaScript and Java" should have a corresponding `id="JavaScript_and_Java"`).
+1. The `.main-section` elements should contain at least ten `p` elements total (not each).
+1. The `.main-section` elements should contain at least five `code` elements total (not each).
+1. The `.main-section` elements should contain at least five `li` items total (not each).
+1. You can see a `nav` element with a corresponding `id="navbar"`.
+1. The navbar element should contain one `header` element which contains text that describes the topic of the technical documentation.
+1. Additionally, the navbar should contain link (`a`) elements with the class of `nav-link`. There should be one for every element with the class `main-section`.
+1. The `header` element in the `#navbar` must come before any link (`a`) elements in the navbar.
+1. Each element with the class of `nav-link` should contain text that corresponds to the `header` text within each `section` (e.g. if you have a "Hello world" section/header, your navbar should have an element which contains the text "Hello world").
+1. When you click on a navbar element, the page should navigate to the corresponding section of the `#main-doc` element (e.g. If you click on a `.nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id, and contains the corresponding header).
+1. On regular sized devices (laptops, desktops), the element with `id="navbar"` should be shown on the left side of the screen and should always be visible to the user.
+1. Your technical documentation should use at least one media query.
+
+**Note:** Be sure to link your stylesheet in your HTML and apply your CSS.
+
+# --hints--
+
+You should have a `main` element with an `id` of `main-doc`.
+
+```js
+const el = document.getElementById('main-doc')
+assert(!!el)
+```
+
+You should have at least five `section` elements with a class of `main-section`.
+
+```js
+const els = document.querySelectorAll('#main-doc section')
+assert(els.length >= 5)
+```
+
+All of your `.main-section` elements should be `section` elements.
+
+```js
+const els = document.querySelectorAll('.main-section')
+els.forEach(el => {
+ if (el.tagName !== 'SECTION') assert(false)
+})
+assert(els.length > 0)
+```
+
+You should have at least five `.main-section` elements that are descendants of `#main-doc`.
+
+```js
+const els = document.querySelectorAll('#main-doc .main-section')
+assert(els.length >= 5)
+```
+
+The first child of each `.main-section` should be a `header` element.
+
+```js
+const els = document.querySelectorAll('.main-section')
+els.forEach(el => {
+ if(el.firstElementChild?.tagName !== 'HEADER') assert(false)
+})
+assert(els.length > 0)
+```
+
+None of your `header` elements should be empty.
+
+```js
+const els = document.querySelectorAll('header')
+els.forEach(el => {
+ if (el.innerText?.length <= 0) assert(false)
+})
+assert(els.length > 0)
+```
+
+All of your `.main-section` elements should have an `id`.
+
+```js
+const els = document.querySelectorAll('.main-section')
+els.forEach(el => {
+ if (!el.id || el.id === '') assert(false)
+})
+assert(els.length > 0)
+```
+
+Each `.main-section` should have an `id` that matches the text of its first child, having any spaces in the child's text replaced with underscores (`_`) for the id's.
+
+```js
+const els = document.querySelectorAll('.main-section')
+els.forEach(el => {
+ const text = el.firstElementChild?.innerText?.replaceAll(' ', '_')
+ if (el.id?.toUpperCase() !== text?.toUpperCase()) assert(false)
+})
+assert(els.length > 0)
+```
+
+You should have at least 10 `p` elements (total) within your `.main-section` elements.
+
+```js
+const els = document.querySelectorAll('.main-section p')
+assert(els.length >= 10)
+```
+
+You should have at least five `code` elements that are descendants of `.main-section` elements.
+
+```js
+const els = document.querySelectorAll('.main-section code')
+assert(els.length >= 5)
+```
+
+You should have at least five `li` elements that are descendants of `.main-section` elements.
+
+```js
+const els = document.querySelectorAll('.main-section li')
+assert(els.length >= 5)
+```
+
+You should have a `nav` element with an `id` of `navbar`.
+
+```js
+const el = document.getElementById('navbar')
+assert(!!el && el.tagName === 'NAV')
+```
+
+Your `#navbar` should have exactly one `header` element within it.
+
+```js
+const els = document.querySelectorAll('#navbar header')
+assert(els.length === 1)
+```
+
+You should have at least one `a` element with a class of `nav-link`.
+
+```js
+const els = document.querySelectorAll('a.nav-link')
+assert(els.length >= 1)
+```
+
+All of your `.nav-link` elements should be anchor (`a`) elements.
+
+```js
+const els = document.querySelectorAll('.nav-link')
+els.forEach(el => {
+ if (el.tagName !== 'A') assert(false)
+})
+assert(els.length > 0)
+```
+
+All of your `.nav-link` elements should be in the `#navbar`.
+
+```js
+const els1 = document.querySelectorAll('.nav-link')
+const els2 = document.querySelectorAll('#navbar .nav-link')
+assert(els2.length > 0 && els1.length === els2.length)
+```
+
+You should have the same number of `.nav-link` and `.main-section` elements.
+
+```js
+const els1 = document.querySelectorAll('.main-section')
+const els2 = document.querySelectorAll('.nav-link')
+assert(els1.length > 0 && els2.length > 0 && els1.length === els2.length)
+```
+
+The `header` element in the `#navbar` should come before any link (`a`) elements also in the `#navbar`.
+
+```js
+const navLinks = document.querySelectorAll('#navbar a.nav-link');
+const header = document.querySelector('#navbar header');
+navLinks.forEach((navLink) => {
+ if (
+ (
+ header.compareDocumentPosition(navLink) &
+ Node.DOCUMENT_POSITION_PRECEDING
+ )
+ ) assert(false)
+});
+assert(!!header)
+```
+
+Each `.nav-link` should have text that corresponds to the `header` text of its related `section` (e.g. if you have a "Hello world" section/header, your `#navbar` should have a `.nav-link` which has the text "Hello world").
+
+```js
+const headerText = Array.from(document.querySelectorAll('.main-section')).map(el =>
+ el.firstElementChild?.innerText?.trim().toUpperCase()
+)
+const linkText = Array.from(document.querySelectorAll('.nav-link')).map(el =>
+ el.innerText?.trim().toUpperCase()
+)
+const remainder = headerText.filter(str => linkText.indexOf(str) === -1)
+assert(headerText.length > 0 && linkText.length > 0 && remainder.length === 0)
+```
+
+Each `.nav-link` should have an `href` attribute that links to its corresponding `.main-section` (e.g. If you click on a `.nav-link` element that contains the text "Hello world", the page navigates to a `section` element with that id).
+
+```js
+const hrefValues = Array.from(document.querySelectorAll('.nav-link')).map(el => el.getAttribute('href'))
+const mainSectionIDs = Array.from(document.querySelectorAll('.main-section')).map(el => el.id)
+const missingHrefValues = mainSectionIDs.filter(str => hrefValues.indexOf('#' + str) === -1)
+assert(hrefValues.length > 0 && mainSectionIDs.length > 0 && missingHrefValues.length === 0)
+```
+
+Your `#navbar` should always be on the left edge of the window.
+
+```js
+const el = document.getElementById('navbar')
+const left1 = el?.offsetLeft
+const left2 = el?.offsetLeft
+assert(!!el && left1 >= -15 && left1 <= 15 && left2 >= -15 && left2 <= 15)
+```
+
+Your Technical Documentation project should use at least one media query.
+
+```js
+const htmlSourceAttr = Array.from(document.querySelectorAll('source')).map(el => el.getAttribute('media'))
+const cssCheck = new __helpers.CSSHelp(document).getCSSRules('media')
+assert(cssCheck.length > 0 || htmlSourceAttr.length > 0);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+ JavaScript is a cross-platform, object-oriented scripting language.
+ It is a small and lightweight language. Inside a host environment
+ (for example, a web browser), JavaScript can be connected to the
+ objects of its environment to provide programmatic control over
+ them.
+
+
+
+ JavaScript contains a standard library of objects, such as Array,
+ Date, and Math, and a core set of language elements such as
+ operators, control structures, and statements. Core JavaScript can
+ be extended for a variety of purposes by supplementing it with
+ additional objects; for example:
+
+
+
+ Client-side JavaScript extends the core language by supplying
+ objects to control a browser and its Document Object Model (DOM).
+ For example, client-side extensions allow an application to place
+ elements on an HTML form and respond to user events such as mouse
+ clicks, form input, and page navigation.
+
+
+ Server-side JavaScript extends the core language by supplying
+ objects relevant to running JavaScript on a server. For example,
+ server-side extensions allow an application to communicate with a
+ database, provide continuity of information from one invocation to
+ another of the application, or perform file manipulations on a
+ server.
+
+
+
+
+
+ What you should already know
+
+
This guide assumes you have the following basic background:
+
+
+
+ A general understanding of the Internet and the World Wide Web
+ (WWW).
+
+
Good working knowledge of HyperText Markup Language (HTML).
+
+ Some programming experience. If you are new to programming, try
+ one of the tutorials linked on the main page about JavaScript.
+
+
+
+
+
+ JavaScript and Java
+
+
+ JavaScript and Java are similar in some ways but fundamentally
+ different in some others. The JavaScript language resembles Java but
+ does not have Java's static typing and strong type checking.
+ JavaScript follows most Java expression syntax, naming conventions
+ and basic control-flow constructs which was the reason why it was
+ renamed from LiveScript to JavaScript.
+
+
+
+ In contrast to Java's compile-time system of classes built by
+ declarations, JavaScript supports a runtime system based on a small
+ number of data types representing numeric, Boolean, and string
+ values. JavaScript has a prototype-based object model instead of the
+ more common class-based object model. The prototype-based model
+ provides dynamic inheritance; that is, what is inherited can vary
+ for individual objects. JavaScript also supports functions without
+ any special declarative requirements. Functions can be properties of
+ objects, executing as loosely typed methods.
+
+
+ JavaScript is a very free-form language compared to Java. You do not
+ have to declare all variables, classes, and methods. You do not have
+ to be concerned with whether methods are public, private, or
+ protected, and you do not have to implement interfaces. Variables,
+ parameters, and function return types are not explicitly typed.
+
+
+
+
+ Hello world
+
+ To get started with writing JavaScript, open the Scratchpad and write
+ your first "Hello world" JavaScript code:
+ function greetMe(yourName) { alert("Hello " + yourName); }
+ greetMe("World");
+
+
+ Select the code in the pad and hit Ctrl+R to watch it unfold in your
+ browser!
+
+
+
+ Variables
+
+ You use variables as symbolic names for values in your application.
+ The names of variables, called identifiers, conform to certain rules.
+
+
+ A JavaScript identifier must start with a letter, underscore (_), or
+ dollar sign ($); subsequent characters can also be digits (0-9).
+ Because JavaScript is case sensitive, letters include the characters
+ "A" through "Z" (uppercase) and the characters "a" through "z"
+ (lowercase).
+
+
+ You can use ISO 8859-1 or Unicode letters such as å and ü in
+ identifiers. You can also use the Unicode escape sequences as
+ characters in identifiers. Some examples of legal names are
+ Number_hits, temp99, and _name.
+
+
+
+ Declaring variables
+
+ You can declare a variable in three ways:
+
+ With the keyword var. For example, var x = 42. This
+ syntax can be used to declare both local and global variables.
+
+
+ By simply assigning it a value. For example,
+ x = 42. This always declares a global variable. It
+ generates a strict JavaScript warning. You shouldn't use this
+ variant.
+
+
+ With the keyword let. For example, let y = 13. This
+ syntax can be used to declare a block scope local variable. See
+ Variable scope below.
+
+
+
+
+ Variable scope
+
+
+ When you declare a variable outside of any function, it is called a
+ global variable, because it is available to any other code in the
+ current document. When you declare a variable within a function, it
+ is called a local variable, because it is available only within that
+ function.
+
+
+
+ JavaScript before ECMAScript 2015 does not have block statement
+ scope; rather, a variable declared within a block is local to the
+ function (or global scope) that the block resides within. For
+ example the following code will log 5, because the scope of x is the
+ function (or global context) within which x is declared, not the
+ block, which in this case is an if statement.
+
+ if (true) { var x = 5; } console.log(x); // 5
+
+ This behavior changes, when using the let declaration introduced in
+ ECMAScript 2015.
+
+
+ if (true) { let y = 5; } console.log(y); // ReferenceError: y is
+ not defined
+
+
+
+ Global variables
+
+
+ Global variables are in fact properties of the global object. In web
+ pages the global object is window, so you can set and access global
+ variables using the window.variable syntax.
+
+
+
+ Consequently, you can access global variables declared in one window
+ or frame from another window or frame by specifying the window or
+ frame name. For example, if a variable called phoneNumber is
+ declared in a document, you can refer to this variable from an
+ iframe as parent.phoneNumber.
+
+
+
+
+ Constants
+
+
+ You can create a read-only, named constant with the const keyword.
+ The syntax of a constant identifier is the same as for a variable
+ identifier: it must start with a letter, underscore or dollar sign
+ and can contain alphabetic, numeric, or underscore characters.
+
+
+ const PI = 3.14;
+
+ A constant cannot change value through assignment or be re-declared
+ while the script is running. It has to be initialized to a value.
+
+
+
+ The scope rules for constants are the same as those for let block
+ scope variables. If the const keyword is omitted, the identifier is
+ assumed to represent a variable.
+
+
+
+ You cannot declare a constant with the same name as a function or
+ variable in the same scope. For example:
+
+
+ // THIS WILL CAUSE AN ERROR function f() {}; const f = 5; // THIS
+ WILL CAUSE AN ERROR ALSO function f() { const g = 5; var g;
+ //statements }
+ However, object attributes are not protected, so the following
+ statement is executed without problems.
+ const MY_OBJECT = {"key": "value"}; MY_OBJECT.key =
+ "otherValue";
+
+
+
+ Data types
+
+
The latest ECMAScript standard defines seven data types:
+
+
+
Six data types that are primitives:
+
+
Boolean. true and false.
+
+ null. A special keyword denoting a null value. Because
+ JavaScript is case-sensitive, null is not the same as Null,
+ NULL, or any other variant.
+
+
+ undefined. A top-level property whose value is undefined.
+
+
Number. 42 or 3.14159.
+
String. "Howdy"
+
+ Symbol (new in ECMAScript 2015). A data type whose instances
+ are unique and immutable.
+
+
+
+
+
and Object
+
+ Although these data types are a relatively small amount, they enable
+ you to perform useful functions with your applications. Objects and
+ functions are the other fundamental elements in the language. You can
+ think of objects as named containers for values, and functions as
+ procedures that your application can perform.
+
+
+
+ if...else statement
+
+ Use the if statement to execute a statement if a logical condition is
+ true. Use the optional else clause to execute a statement if the
+ condition is false. An if statement looks as follows:
+
+ if (condition) { statement_1; } else { statement_2; }
+ condition can be any expression that evaluates to true or false. See
+ Boolean for an explanation of what evaluates to true and false. If
+ condition evaluates to true, statement_1 is executed; otherwise,
+ statement_2 is executed. statement_1 and statement_2 can be any
+ statement, including further nested if statements.
+
+ You may also compound the statements using else if to have multiple
+ conditions tested in sequence, as follows:
+
+ if (condition_1) { statement_1; } else if (condition_2) {
+ statement_2; } else if (condition_n) { statement_n; } else {
+ statement_last; }
+
+ 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 ({ ... }) . In
+ general, it's good practice to always use block statements, especially
+ when nesting if statements:
+
+ if (condition) { statement_1_runs_if_condition_is_true;
+ statement_2_runs_if_condition_is_true; } else {
+ statement_3_runs_if_condition_is_false;
+ statement_4_runs_if_condition_is_false; }
+ 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:
+ if (x = y) { /* statements here */ } If you need to use
+ an assignment in a conditional expression, a common practice is to put
+ additional parentheses around the assignment. For example:
+
+ if ((x = y)) { /* statements here */ }
+
+
+
+ while statement
+
+ A while statement executes its statements as long as a specified
+ condition evaluates to true. A while statement looks as follows:
+
+ while (condition) statement If the condition becomes
+ false, statement within the loop stops executing and control passes to
+ the statement following the loop.
+
+
+ The condition test occurs before statement in the loop is executed.
+ If the condition returns true, statement is executed and the
+ condition is tested again. If the condition returns false, execution
+ stops and control is passed to the statement following while.
+
+
+
+ To execute multiple statements, use a block statement ({ ... }) to
+ group those statements.
+
+
+ Example:
+
+
+ The following while loop iterates as long as n is less than three:
+
+
+ var n = 0; var x = 0; while (n < 3) { n++; x += n; }
+
+ With each iteration, the loop increments n and adds that value to x.
+ Therefore, x and n take on the following values:
+
+
+
+
After the first pass: n = 1 and x = 1
+
After the second pass: n = 2 and x = 3
+
After the third pass: n = 3 and x = 6
+
+
+ After completing the third pass, the condition n < 3 is no longer
+ true, so the loop terminates.
+
+
+
+
+ Function declarations
+
+ A function definition (also called a function declaration, or function
+ statement) consists of the function keyword, followed by:
+
+
+
The name of the function.
+
+ A list of arguments to the function, enclosed in parentheses and
+ separated by commas.
+
+
+ The JavaScript statements that define the function, enclosed in
+ curly brackets, { }.
+
+
+
+ For example, the following code defines a simple function named
+ square:
+
+
+ function square(number) { return number * number; }
+
+ The function square takes one argument, called number. The function
+ consists of one statement that says to return the argument of the
+ function (that is, number) multiplied by itself. The return
+ statement specifies the value returned by the function.
+
+ return number * number;
+
+ Primitive parameters (such as a number) are passed to functions by
+ value; the value is passed to the function, but if the function
+ changes the value of the parameter, this change is not reflected
+ globally or in the calling function.
+
+
+
+
+ Reference
+
+
+
+ All the documentation in this page is taken from
+ MDN
+