Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: js 22 cert #1282

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion mobile-app/lib/models/learn/curriculum_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,12 @@ class Block {
});

static bool checkIfStepBased(String superblock) {
return superblock == '2022/responsive-web-design';
List<String> stepBasedSuperBlocks = [
'2022/responsive-web-design',
'javascript-algorithms-and-data-structures-v8'
];

return stepBasedSuperBlocks.contains(superblock);
}

factory Block.fromJson(
Expand Down
44 changes: 19 additions & 25 deletions mobile-app/lib/ui/views/learn/block/block_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:freecodecamp/ui/views/learn/block/block_viewmodel.dart';
import 'package:freecodecamp/ui/views/learn/widgets/download_button_widget.dart';
import 'package:freecodecamp/ui/views/learn/widgets/open_close_icon_widget.dart';
import 'package:freecodecamp/ui/views/learn/widgets/progressbar_widget.dart';
import 'package:freecodecamp/ui/views/news/html_handler/html_handler.dart';
import 'package:freecodecamp/ui/widgets/drawer_widget/drawer_widget_view.dart';

import 'package:stacked/stacked.dart';
Expand Down Expand Up @@ -46,6 +47,8 @@ class BlockView extends StatelessWidget {

bool hasProgress = calculateProgress > 0;

HTMLParser parser = HTMLParser(context: context);

return Column(
children: [
BlockHeader(
Expand Down Expand Up @@ -75,15 +78,9 @@ class BlockView extends StatelessWidget {
vertical: 8,
horizontal: 16,
),
child: Text(
blockString,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
height: 1.2,
fontFamily: 'Lato',
color: Colors.white.withOpacity(0.87),
),
child: Wrap(
children: parser.parse('<p>$blockString</p>',
fontColor: Colors.white),
),
),
if (model.isDev && !isCertification)
Expand Down Expand Up @@ -221,33 +218,30 @@ class BlockHeader extends StatelessWidget {
model.isOpen,
);
},
minVerticalPadding: 24,
minVerticalPadding: 18,
leading: !isCertification
? model.challengesCompleted == block.challenges.length
? const Icon(
Icons.check_circle,
size: 20,
)
: const Icon(
Icons.circle_outlined,
size: 20,
)
: null,
trailing: !isCertification
? OpenCloseIcon(
block: block,
model: model,
)
: null,
title: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (!isCertification)
Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
child: model.challengesCompleted == block.challenges.length
? const Icon(
Icons.check_circle,
size: 20,
)
: const Icon(
Icons.circle_outlined,
size: 20,
),
),
Expanded(
child: Text(
block.name,
maxLines: 2,
maxLines: model.isOpen ? 5 : 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontWeight: FontWeight.bold,
Expand Down
228 changes: 228 additions & 0 deletions mobile-app/lib/ui/views/learn/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
[log]
<html>
<head>
<script src="https://unpkg.com/[email protected]/chai.js"></script>
<script src="https://unpkg.com/mocha/mocha.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/mocha/mocha.css" />
<script type="module" id="fcc-script">
import * as __helpers from "https://www.unpkg.com/@freecodecamp/[email protected]/dist/index.mjs";

const code = `<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input type="number" min="0" id="budget" placeholder="Daily calorie budget" required="">
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected="">Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>


</body></html>:root {
--light-grey: #f5f6f7;
--dark-blue: #0a0a23;
--fcc-blue: #1b1b32;
--light-yellow: #fecc4c;
--dark-yellow: #feac32;
--light-pink: #ffadad;
--dark-red: #850000;
--light-green: #acd157;
}

body {
font-family: "Lato", Helvetica, Arial, sans-serif;
font-size: 18px;
background-color: var(--fcc-blue);
color: var(--light-grey);
}

h1 {
text-align: center;
}

.container {
width: 90%;
max-width: 680px;
}

h1,
.container,
.output {
margin: 20px auto;
}

label,
legend {
font-weight: bold;
}

.input-container {
display: flex;
flex-direction: column;
}

button {
cursor: pointer;
text-decoration: none;
background-color: var(--light-yellow);
border: 2px solid var(--dark-yellow);
}

button,
input,
select {
min-height: 24px;
color: var(--dark-blue);
}

fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}

.output {
border: 2px solid var(--light-grey);
padding: 10px;
text-align: center;
}

.hide {
display: none;
}

.output span {
font-weight: bold;
font-size: 1.2em;
}

.surplus {
color: var(--light-pink);
}

.deficit {
color: var(--light-green);
}
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
`;
const doc = new DOMParser().parseFromString(code, "text/html");

const assert = chai.assert;
const tests = [
`assert.isDefined(budgetNumberInput);`,
`assert.match(code, /document\\.getElementById\\(\\s*('|")budget\\1\\s*\\)/g);`,
`assert.equal(budgetNumberInput, document.getElementById('budget'));`,
`assert.isDefined(entryDropdown);`,
`assert.match(code, /document\\.getElementById\\(\\s*('|")entry-dropdown\\1\\s*\\)/g);`,
`assert.equal(entryDropdown, document.getElementById('entry-dropdown'));`,
];
const testText = [
`<p>You should declare a variable called <code>budgetNumberInput</code>.</p>`,
`<p>You should use <code>document.getElementById()</code> to get the <code>#budget</code> element.</p>`,
`<p>You should store the <code>#budget</code> element in a variable called <code>budgetNumberInput</code>.</p>`,
`<p>You should declare a variable called <code>entryDropdown</code>.</p>`,
`<p>You should use <code>document.getElementById()</code> to get the <code>#entry-dropdown</code> element.</p>`,
`<p>You should store the <code>#entry-dropdown</code> element in a variable called <code>entryDropdown</code>.</p>`,
];

function getUserInput(returnCase) {
switch (returnCase) {
case "index":
return `
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
`;
case "editableContents":
return `
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
`;
default:
return code;
}
}

doc.__runTest = async function runtTests(testString) {
let error = false;
for (let i = 0; i < testString.length; i++) {
try {
const testPromise = new Promise((resolve, reject) => {
try {
const test = eval(testString[i]);
resolve(test);
} catch (e) {
reject(e);
}
});
await testPromise;
} catch (e) {
error = true;
console.log("testMSG: " + testText[i]);
break;
}
}
if (!error) {
console.log("completed");
}
};

document.querySelector("*").innerHTML = code;
doc.__runTest(tests);
</script>
</head>
<body></body>
</html>
Loading
Loading