Skip to content
Snippets Groups Projects
Commit accef06e authored by Gauthier Solignac's avatar Gauthier Solignac
Browse files

Fin tp 2

parent cb202be9
No related branches found
No related tags found
No related merge requests found
{
"presets": ["@babel/env"]
"presets": [
["@babel/env", {"modules": false}]
],
"plugins": ["@babel/plugin-proposal-class-properties"]
}
\ No newline at end of file
{
"singleQuote": true,
"trailingComma": "es5",
"endOfLine": "lf",
"useTabs": true,
"arrowParens": "avoid"
}
{
"[javascript]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
......@@ -14,8 +14,7 @@
<link rel="stylesheet" href="css/pizzaList.css">
<link rel="stylesheet" href="css/footer.css">
<script src="build/main.js" defer></script>
</head>
<script defer src="build/main.bundle.js"></script></head>
<body>
<header>
<nav>
......
This diff is collapsed.
......@@ -4,7 +4,9 @@
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode=production",
"watch": "webpack --mode=development --watch"
},
"author": "Thomas Fritsch <thomas.fritsch@univ-lille.fr> (https://gitlab.univ-lille.fr/thomas.fritsch)",
"homepage": "https://gitlab.univ-lille.fr/js",
......@@ -12,6 +14,11 @@
"devDependencies": {
"@babel/cli": "^7.12.10",
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11"
"@babel/plugin-proposal-class-properties": "^7.12.13",
"@babel/preset-env": "^7.12.11",
"babel-loader": "^8.2.2",
"prettier": "^2.2.1",
"webpack": "^5.20.0",
"webpack-cli": "^4.5.0"
}
}
import Component from "./components/Component";
export default class Router {
static titleElement;
static contentElement;
static routes;
static navigate(path) {
//console.log(this.routes[0].page.pizzas);
this.routes.forEach((element) => {
if (element.path == path) {
const c = new Component("h1", null, element.title);
this.titleElement.innerHTML = c.render();
console.log(element.page.pizzas);
this.contentElement.innerHTML = element.page.render();
}
});
}
}
export default class Component {
tagName;
children;
attribute;
constructor(tagName, attribute, children) {
this.tagName = tagName;
this.children = children;
this.attribute = attribute;
}
render() {
return `
<${this.tagName} ${this.renderAttribute()}>
${this.renderChildren()}
</${this.tagName}>`;
}
renderChildren() {
if (Array.isArray(this.children)) {
return this.children.reduce((acc, child) => {
return acc + this.renderChild(child);
}, "");
} else {
return this.renderChild(this.children);
}
}
renderAttribute() {
if (this.attribute) {
return `${this.attribute.name}="${this.attribute.value}"`;
} else {
return "";
}
}
renderChild(child) {
if (child instanceof Component) {
return child.render();
} else {
return child;
}
}
}
import Component from "./Component";
export default class Img extends Component {
constructor(src) {
super("img", { name: "src", value: src }, null);
}
render() {
return `<${this.tagName} ${this.attribute.name}=${this.attribute.value}/>`;
}
}
import Component from "./Component";
import Img from "./Img";
export default class PizzaThumbnail extends Component {
constructor({ name, image, price_small, price_large }) {
super("article", { name: "class", value: "pizzaThumbnail" }, [
new Component("a", { name: "href", value: image }, [
new Img(image),
new Component("section", null, [
new Component("h4", null, name),
new Component("ul", null, [
new Component(
"li",
null,
`Prix petit format : ${price_small.toFixed(2)} €`
),
new Component(
"li",
null,
`Prix grand format : ${price_large.toFixed(2)} €`
),
]),
]),
]),
]);
}
}
const data = [
{
name: "Regina",
base: "tomate",
price_small: 6.5,
price_large: 9.95,
image:
"https://images.unsplash.com/photo-1532246420286-127bcd803104?fit=crop&w=500&h=300",
},
{
name: "Napolitaine",
base: "tomate",
price_small: 6.5,
price_large: 8.95,
image:
"https://images.unsplash.com/photo-1562707666-0ef112b353e0?&fit=crop&w=500&h=300",
},
{
name: "Spicy",
base: "crème",
price_small: 5.5,
price_large: 8,
image:
"https://images.unsplash.com/photo-1458642849426-cfb724f15ef7?fit=crop&w=500&h=300",
},
];
export default data;
// D. Manipulation des chaînes
import Component from "./components/Component.js";
import Img from "./components/Img.js";
import data from "./data.js";
import PizzaThumbnail from "./components/PizzaThumbnail.js";
import PizzaList from "./page/PizzaList.js";
import Router from "./Router";
// const name = 'Regina';
// const url = `images/${name.toLowerCase()}.jpg`;
// const html = `
// <article class="pizzaThumbnail">
// <a href="${url}">
// <img src="${url}" />
// <section>${name}</section>
// </a>
// </article>
// `;
// document.querySelector('.pageContent').innerHTML = html;
//const titletest = new Component("h1", null, "La carte");
//document.querySelector(".pageTitle").innerHTML = title.render();
//console.log(titletest.render());
// // E.1. Manipulation des tableaux
// let data = [ 'Regina', 'Napolitaine', 'Spicy' ];
// html = '';
// // E.1. boucle for :
// for (let i = 0; i < data.length; i++) {
// const nom = data[i],
// url = `images/${nom.toLowerCase()}.jpg`;
// html += `<article class="pizzaThumbnail">
// <a href="${url}">
// <img src="${url}" />
// <section>${nom}</section>
// </a>
// </article>`;
// }
// document.querySelector('.pageContent').innerHTML = html;
/*const title = new Component("h1", null, ["La", " ", "carte"]);
document.querySelector(".pageTitle").innerHTML = title.render();
// E.1. Array.forEach :
// html = '';
// data.forEach( nom => {
// const url = `images/${nom.toLowerCase()}.jpg`;
// html += `<a href="${url}">
// <img src="${url}" />
// <h4>${nom}</h4>
// </a>`;
// })
// document.querySelector('.pageContent').innerHTML = html;
/*const pizza = data[0];
const pizzaThumbnail = new PizzaThumbnail(pizza);
document.querySelector(".pageContent").innerHTML = pizzaThumbnail.render();
// // E.1. Array.map + Array.join :
// html = data.map( nom => `<a href="images/${nom.toLowerCase()}.jpg">
// <img src="images/${nom.toLowerCase()}.jpg" />
// <h4>${nom}</h4>
// </a>`).join('');
// document.querySelector('.pageContent').innerHTML = html;
// `data` est le tableau défini dans `src/data.js`
// // E.1. Array.reduce :
// html = data.reduce( (str, nom) => str+`<a href="images/${nom.toLowerCase()}.jpg">
// <img src="images/${nom.toLowerCase()}.jpg" />
// <h4>${nom}</h4>
// </a>`,'');
// document.querySelector('.pageContent').innerHTML = html;
//document.querySelector(".pageContent").innerHTML = pizzaList.render();*/
//const pizzaList = new PizzaList(data);
// E.2. Les objets littéraux
const data = [
{
name: 'Regina',
base: 'tomate',
price_small: 6.5,
price_large: 9.95,
image: 'https://images.unsplash.com/photo-1532246420286-127bcd803104?fit=crop&w=500&h=300'
},
{
name: 'Napolitaine',
base: 'tomate',
price_small: 6.5,
price_large: 8.95,
image: 'https://images.unsplash.com/photo-1562707666-0ef112b353e0?&fit=crop&w=500&h=300'
},
{
name: 'Spicy',
base: 'crème',
price_small: 5.5,
price_large: 8,
image: 'https://images.unsplash.com/photo-1458642849426-cfb724f15ef7?fit=crop&w=500&h=300',
}
];
Router.titleElement = document.querySelector(".pageTitle");
Router.contentElement = document.querySelector(".pageContent");
/*Router.routes = [{ path: "/", page: pizzaList, title: "La carte" }];
Router.navigate("/");*/
function render(pizzas) {
const html = pizzas.reduce( (str, {image, name, price_small, price_large}) => str +
`<article class="pizzaThumbnail">
<a href="${image}">
<img src="${image}" />
<section>
<h4>${name}</h4>
<ul>
<li>Prix petit format : ${price_small.toFixed(2)} €</li>
<li>Prix grand format : ${price_large.toFixed(2)} €</li>
</ul>
</section>
</a>
</article>`, '');
document.querySelector('.pageContent').innerHTML = html;
}
const pizzaList = new PizzaList([]);
Router.routes = [{ path: "/", page: pizzaList, title: "La carte" }];
// G.1. Tri de tableaux
function sortByName(a, b) {
if ( a.name < b.name ) {
return -1;
} else if ( a.name > b.name ) {
return 1;
}
return 0;
}
//Router.navigate("/"); // affiche une page vide
pizzaList.pizzas = data;
// tri par price_small croissant PUIS par price_large croissant
function sortByPrice(a, b) {
if ( a.price_small !== b.price_small ) {
return a.price_small - b.price_small;
}
return a.price_large - b.price_large;
}
// // Attention : data.sort() modifie le tableau original
render( data );
// render( data.sort(sortByName) );
// render( data.sort(sortByPrice) );
// // G.2. Système de filtre
// render( data.filter( pizza => pizza.base == 'tomate' ))
// render( data.filter( pizza => pizza.price_small < 6 ))
// // deux possibilités pour les pizzas avec deux fois la lettre "i"
// render( data.filter( pizza => pizza.name.split('i').length == 3 ))
// render( data.filter( pizza => pizza.name.match(/i/g).length == 2 ))
// // G.3. Destructuring
// render( data.filter( ({base}) => base == 'tomate' ))
// render( data.filter( ({price_small}) => price_small < 6 ))
// render( data.filter( ({name}) => name.match(/i/g).length === 2 ));
Router.navigate("/"); // affiche la liste des pizzas
import Component from "../components/Component";
import PizzaThumbnail from "../components/PizzaThumbnail";
export default class PizzaList extends Component {
#pizzas;
constructor(pizzas) {
super(
"section",
{ name: "class", value: "pizzaList" },
pizzas.map((pizza) => {
return new PizzaThumbnail(pizza);
})
);
this.#pizzas = pizzas;
}
set pizzas(pizzas) {
this.#pizzas = pizzas;
}
get pizzas() {
return this.#pizzas;
}
}
const path = require("path");
module.exports = {
// Fichier d'entrée :
entry: "./src/main.js",
// Fichier de sortie :
output: {
path: path.resolve(__dirname, "./build"),
filename: "main.bundle.js",
},
// compatibilité anciens navigateurs (si besoin du support de IE11 ou android 4.4)
target: ["web", "es5"],
// connexion webpack <-> babel :
module: {
rules: [
{
test: /\.js$/, // tous les fichiers js ...
exclude: /node_modules/, // ... sauf le dossier node_modules ...
use: {
// ... seront compilés par babel !
loader: "babel-loader",
},
},
],
},
devtool: "source-map",
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment